Collection Update

Issue #119 This is about collection update, how to provide correct IndexPath and a simple diffing algorithm Excerpt from my talk at CocoaHeads, Oslo https://www.meetup.com/CocoaHeads-Oslo/events/244892347/ Slide https://speakerdeck.com/onmyway133/collection-update CollectionView It’s hard to imagine of any apps that don’t use Table View or CollectionView. And by CollectionView, I actually mean UICollectionView 😉 . Most of the time, we show something with response from backend, then potentially update and insert new items as data changed....

December 7, 2017 · 8 min · 1666 words · Khoa

Using Playground with CocoaPods

Issue #113 This is a follow up from my post Learning from Open Source: Using Playground on how to actually add a playground to your production project. The idea is simple: create a framework so that Playground can access the code. This demo an iOS project with CocoaPods. See the demo https://github.com/onmyway133/UsingPlayground This is also my question to this question https://stackoverflow.com/questions/47589855/how-to-expose-your-project-code-to-a-xcode-playground-when-using-cocoapods/47595120#47595120 1. Add a pod Create a new project called UsingPlayground....

December 1, 2017 · 2 min · 373 words · Khoa

URL Routing with Compass

Issue #110 Medium version https://medium.com/@onmyway133/url-routing-with-compass-d59c0061e7e2 Apps often have many screens, and UIViewController works well as the basis for a screen, together with presentation and navigation APIs. Things are fine until you get lost in the forest of flows, and code becomes hard to maintain. One way to avoid this is the central URL routing approach. Think of it as a network router that handles and resolves all routing requests. This way, the code becomes declarative and decoupled, so that the list component does not need to know what it’s presenting....

November 27, 2017 · 18 min · 3654 words · Khoa

Coordinator and FlowController

Issue #106 Every new architecture that comes out, either iOS or Android, makes me very excited. I’m always looking for ways to structure apps in a better way. But after some times, I see that we’re too creative in creating architecture, aka constraint, that is too far away from the platform that we’re building. I often think “If we’re going too far from the system, then it’s very hard to go back”...

November 14, 2017 · 11 min · 2169 words · Khoa

Please reconsidering your choice of libraries

Issue #105 Are you willing to take vaccines you don’t know about? I like open source. I ’ve made some and contributed to some. I also use other people ’s open source libraries and learn a lot from them 😇 Open source can help us build better, faster and maybe more performant software by basing on other people ’s hard work. We can also collaborate and make it better. But it’s also a double edges sword if you’re not judging carefully....

November 10, 2017 · 3 min · 620 words · Khoa

Diff algorithm

Issue #99 I’ve been searching for efficient ways to diff collections, here are some interesting papers that I find Myers An O(ND) Difference Algorithm and Its Variations https://github.com/wokalski/Diff.swift https://github.com/kpdecker/jsdiff https://github.com/raywenderlich/swift-algorithm-club/pull/693/files Wu An O(NP) Sequence Comparison Algorithm https://github.com/kazuhiro4949/EditDistance https://github.com/cubicdaiya/onp https://github.com/hattya/go.diff/blob/master/diff.go https://gist.github.com/tociyuki/acedd33ca4913f1ab8e9 http://t2y.hatenablog.jp/entry/20090802/1249146010 Wagner–Fischer https://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm) http://davedelong.tumblr.com/post/134367865668/edit-distance-and-edit-steps https://github.com/osteslag/Changeset https://github.com/onmyway133/DeepDiff Common Longest Subsequence https://en.wikipedia.org/wiki/Longest_common_subsequence_problem https://github.com/jflinter/Dwifft https://github.com/Frugghi/SwiftLCS Heckel http://documents.scribd.com/docs/10ro9oowpo1h81pgh1as.pdf A technique for isolating differences between files https://github.com/mcudich/HeckelDiff IGListDiff https://github.com/andre-alves/PHDiff https://gist.github.com/ndarville/3166060 https://github.com/myndzi/heckel-diff https://johnresig.com/projects/javascript-diff-algorithm/ https://stackoverflow.com/questions/42755035/difficulty-understanding-paul-heckels-diff-algorithm https://github.com/RACCommunity/FlexibleDiff/blob/diffing/FlexibleDiff/Changeset.swift https://github.com/onmyway133/DeepDiff https://github....

October 31, 2017 · 1 min · 84 words · Khoa

How to use safeAreaLayoutGuide in iOS 10

Issue #98 The safeAreaLayoutGuide was introduced in iOS 11. And it is advised to stop using topLayoutGuide bottomLayoutGuide as these are deprecated. To use safeAreaLayoutGuide, you need to do iOS version check if #available(iOS 11.0, *) { headerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20) } else { headerView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20) } Maybe we can introduce a common property that can be used across many iOS versions, let’s call it compatibleSafeAreaLayoutGuide extension UIView { /// Use safeAreaLayoutGuide on iOS 11+, otherwise default to dummy layout guide var compatibleSafeAreaLayoutGuide: UILayoutGuide { if #available(iOS 11, *) { return safeAreaLayoutGuide } else { if let layoutGuide = self....

October 31, 2017 · 1 min · 186 words · Khoa

Learning from Open Source Using Coordinator

Issue #97 The Coordinator pattern can be useful to manage dependencies and handle navigation for your view controllers. It can be seen from BackchannelSDK-iOS, take a look at BAKCreateProfileCoordinator for example @implementation BAKCreateProfileCoordinator - (instancetype)initWithUser:(BAKUser *)user navigationController:(UINavigationController *)navigationController configuration:(BAKRemoteConfiguration *)configuration { self = [super init]; if (!self) return nil; _navigationController = navigationController; _user = user; _profileViewController = [[BAKProfileFormViewController alloc] init]; [self configureProfileForm]; _configuration = configuration; return self; } - (void)start { [self....

October 25, 2017 · 1 min · 124 words · Khoa

Learning from Open Source Managing dependencies

Issue #96 Another cool thing about ios-oss is how it manages dependencies. Usually you have a lot of dependencies, and it’s good to keep them in one place, and inject it to the objects that need. The Environment is simply a struct that holds all dependencies throughout the app /** A collection of **all** global variables and singletons that the app wants access to. */ public struct Environment { /// A type that exposes endpoints for fetching Kickstarter data....

October 25, 2017 · 3 min · 440 words · Khoa

Learning from Open Source Using Playground

Issue #94 One thing I like about kickstarter-ios is how they use Playground to quickly protoyping views. We use Swift Playgrounds for iterative development and styling. Most major screens in the app get a corresponding playground where we can see a wide variety of devices, languages and data in real time. This way we don’t need Injection or using React Native anymore. Take a look at all the pages https://github.com/kickstarter/ios-oss/tree/master/Kickstarter-iOS.playground/Pages...

October 23, 2017 · 1 min · 87 words · Khoa

Indenting Swift code

Issue #93 Hi, here is how I indent my code. Let me know what you think 😉 Using 2 spaces indentation When possible, configure your editor to use 2 spaces for tab size. You will love it ❤️ Move first parameter to new line If there are many parameters, move the first parameter to a new line, and align the other parameters. Remember that the last parenthesis ) should align to the function call...

October 20, 2017 · 2 min · 225 words · Khoa

Sync and async code in Swift

Issue #75 We should use DispatchQueue to build thread safe code. The idea is to prevent two read and write from happening at the same time from 2 different threads, which cause data corruption and unexpected behaviors. Note that you should try to avoid deadlock https://stackoverflow.com/questions/15381209/how-do-i-create-a-deadlock-in-grand-central-dispatch All sync Use try catch, together with serial queue. Use sync function to block current queue. func getUser(id: String) throws -> User { var user: User!...

September 14, 2017 · 2 min · 326 words · Khoa

How to use Given When Then in Swift tests

Issue #73 Spec Using spec testing framework like Quick is nice, which enables BDD style. describe("the 'Documentation' directory") { it("has everything you need to get started") { let sections = Directory("Documentation").sections expect(sections).to(contain("Organized Tests with Quick Examples and Example Groups")) expect(sections).to(contain("Installing Quick")) } context("if it doesn't have what you're looking for") { it("needs to be updated") { let you = You(awesome: true) expect{you.submittedAnIssue}.toEventually(beTruthy()) } } } But in case you don’t want additional frameworks, and want to live closer to Apple SDKs as much as possible, here are few tips....

September 13, 2017 · 2 min · 289 words · Khoa

Optional of optional in Swift

Issue #58 Do you know that an optional can itself contain an optional, that contains another optional? In that case, we need to unwrap multiple times You mostly see it when you try to access window let window = UIApplication.shared.delegate?.window // UIWindow?? It is because delegate can be nil, and its window can be nil too. window??.backgroundColor = .yellow

June 14, 2017 · 1 min · 59 words · Khoa

How to change year in Date in Swift

Issue #54 Today I’m trying to change the year of a Date object to 2000 in Swift. let date = Date() Firstly, I tried with date(bySetting:) but it does not work with past year. It simply returns nil Calendar.current.date(bySetting: .year, value: 2000, of: date) Secondly, I tried with dateComponents. The component.year has changed, but it calendar still returns the original date, very strange !!. No matter what timezone and calendar I use, it still has this problem...

June 9, 2017 · 1 min · 116 words · Khoa

How to run UI Test with system alert in iOS

Issue #48 Continue my post https://github.com/onmyway133/blog/issues/45. When you work with features, like map view, you mostly need permissions, and in UITests you need to test for system alerts. Add interruption monitor This is the code. Note that you need to call app.tap() to interact with the app again, in order for interruption monitor to work addUIInterruptionMonitor(withDescription: "Location permission", handler: { alert in alert.buttons["Allow"].tap() return true }) app.tap() Note that you don’t always need to handle the returned value of addUIInterruptionMonitor...

June 2, 2017 · 2 min · 396 words · Khoa

How to run UITests with map view in iOS

Issue #45 Mock a location You should mock a location to ensure reliable test Create the gpx file Go to Xcode -> File -> New -> GPX File It looks like <?xml version="1.0"?> <gpx version="1.1" creator="Xcode"> <wpt lat="59.913590" lon="10.733750"> <name>Oslo S</name> <time>2017-05-31T14:55:37Z</time> </wpt> <wpt lat="59.913590" lon="10.733750"> <name>Oslo S</name> <time>2017-05-31T14:55:40Z</time> </wpt> </gpx> The gpx file is very powerful, as it allows you to specify a route with different movement speed. Provide one or more waypoints containing a latitude/longitude pair....

June 1, 2017 · 2 min · 371 words · Khoa

How to use MainController in iOS

Issue #36 Usually in an app, we have these flows: onboarding, login, main. And we usually set OnboardingController, LoginController and MainController as the root view controller respectively depending on the state. I find it useful to have the MainController as the container for main flow. It can be a tab controller, swipe menu controller or contains just 1 child view controller. The screens are provided by child view controllers, but the MainController does the following jobs...

May 12, 2017 · 1 min · 194 words · Khoa

How to handle Auto Layout with different screen sizes

Issue #35 Auto Layout is awesome. Just declare the constraints and the views are resized accordingly to their parent ’s bounds changes. But sometimes it does not look good, because we have fixed values for padding, width, height, and even fixed font size. Read more How to make Auto Layout more convenient in iOS This can be solved by some degree using Size Class. The idea of size class is that we have many sets of constraints, and based on the device traits, we enabled some of them....

May 12, 2017 · 2 min · 396 words · Khoa

NSApplicationDelegate and notification

Issue #34 In an iOS project, we often see this in AppDelegate @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { return true } } But in a Cocoa project, we see this instead @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(aNotification: NSNotification) { // Insert code here to initialize your application } func applicationWillTerminate(aNotification: NSNotification) { // Insert code here to tear down your application } } In this case the param is of type NSNotification...

May 10, 2017 · 1 min · 172 words · Khoa