This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# docs: https://docs.microsoft.com/en-us/appcenter/build/custom/scripts/ | |
# Increment build version on Release | |
# format: %Y%m%d.%H%M | |
# reference: https://gist.github.com/sekati/3172554 | |
if [ "${CONFIGURATION}" = "Release" ]; then | |
echo "----" | |
buildNumber=$(TZ="Asia/Ho_Chi_Minh" date +%Y%m%d.%H%M) | |
echo "Build # set to: $buildNumber" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://kean.blog/post/swiftui-data-flow | |
struct SearchView: View { | |
@ObservedObject var viewModel: SearchViewModel | |
var body: some View { | |
VStack { | |
TextField("Search", text: $viewModel.query) | |
List(viewModel.songs) { | |
Text($0.name) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LocalConfigLoader: LocalConfigLoading { | |
private var cachedConfigUrl: URL? { | |
guard let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { | |
return nil | |
} | |
return documentsUrl.appendingPathComponent("config.json") | |
} | |
private var cachedConfig: AppConfig? { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Orginal code from: https://gist.github.com/mecid/f8859ea4bdbd02cf5d440d58e936faec | |
//I just made some modification in appearnce, show monthly navigator and weekdays. | |
import SwiftUI | |
struct ContentView: View { | |
@Environment(\.calendar) var calendar | |
private var year: DateInterval { | |
calendar.dateInterval(of: .month, for: Date())! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let notificationCenter = NotificationCenter.default | |
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil) | |
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) | |
@objc func adjustForKeyboard(notification: Notification) { | |
guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return } | |
let keyboardScreenEndFrame = keyboardValue.cgRectValue | |
let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Diffable datasource and compositional layout: | |
+ https://www.donnywals.com/modern-table-views-with-diffable-data-sources/ | |
+ https://www.swiftbysundell.com/articles/building-modern-collection-views-in-swift/ | |
> **UICollectionViewDiffableDataSource** let us compute UICollectionView datasource and configuration, as a replacement for plain old UICollectionViewDatasource/UICollectionViewDelegate. We also have table view counter part, they are **UITableViewDiffableDataSource**. | |
> we can now use **UICollectionViewComposableLayout** as replacement for **UITableView**. | |
```swift | |
func makeCollectionView() -> UICollectionView { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Latency Comparison Numbers (~2012) | |
---------------------------------- | |
L1 cache reference 0.5 ns | |
Branch mispredict 5 ns | |
L2 cache reference 7 ns 14x L1 cache | |
Mutex lock/unlock 25 ns | |
Main memory reference 100 ns 20x L2 cache, 200x L1 cache | |
Compress 1K bytes with Zippy 3,000 ns 3 us | |
Send 1K bytes over 1 Gbps network 10,000 ns 10 us | |
Read 4K randomly from SSD* 150,000 ns 150 us ~1GB/sec SSD |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This file contains the fastlane.tools configuration | |
# You can find the documentation at https://docs.fastlane.tools | |
# | |
# For a list of all available actions, check out | |
# | |
# https://docs.fastlane.tools/actions | |
# | |
# Uncomment the line if you want fastlane to automatically update itself | |
# update_fastlane |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// mocking in swift | |
// reference: https://www.vadimbulavin.com/real-world-unit-testing-in-swift/ | |
struct User {} | |
class AuthService { | |
var client: HTTPClient | |
// init | |
init(_ client: HTTPClient) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum GitHubAPIError: Error { | |
case userIsEmpty | |
case invalidData | |
} | |
func fetchGithubUser(_ user: String) -> Single<[String: Any]> { | |
guard user.isEmpty == false else { return Single.error(GitHubAPIError.userIsEmpty) } | |
return Single<[String: Any]>.create(subscribe: { completion in | |
let task = URLSession.shared | |
.dataTask(with: URLRequest(url: URL(string: "https://api.github.com/users/\(user)")!), completionHandler: { data, _, error in |