Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MapStack - lesson 7

leveton
March 11, 2016
36

MapStack - lesson 7

leveton

March 11, 2016
Tweet

Transcript

  1. GCD - Grand Central Dispatch GCD facilitates multi-threading by abstracting

    away the hard parts. Things like locking to avoid race conditions (we touched on this in atomic vs. nonatomic). Look at the dispatch_async C function in layoutMapWithDictionary:. It takes two arguments: a function and a block (yes, more blocks). Cmd+click into ‘dispatch_get_main_queue()’ to reveal its implementation:
  2. GCD - Grand Central Dispatch What’s happening here is we

    are asking the system’s runtime to asynchronously run some process on the main thread - sending it a serial queue of tasks to perform. We want it done asynchronously so that it occurs without interfering with the current process (in this case downloading from a webservice). We want it done serially so that the code in the block is performed in order and not at the same time.
  3. GCD - Grand Central Dispatch What happens if we remove

    the call to dispatch_async() in layoutMapWithDictionary? Try it and you’ll find that the map is no longer annotated with pins. (Jerk the map a little and the pins appear because MapKit reloads with a full datasource).
  4. GCD - Grand Central Dispatch By calling dispatch_get_main_queue() asynchronously and

    sending it a block of code to execute, we can “force” the UI to be responsive. This is critical for user experience.
  5. Subclassing UIView to create a progress view UIView is probably

    the second most subclassed class in iOS behind NSObject. When our users are on 3G or something less powerful, there will be a noticeable delay in the loading of locations. Let’s make a progress view for our map and use that to investigate UIView’s properties.
  6. Subclassing UIView to create a progress view Problem: we want

    a gradient but we can’t use a pre-made image because it’s not flexible. Solution: We override drawRect: and drop down into C
  7. Subclassing UIView to create a progress view Overriding drawRect should

    only be done as a last resort because it’s CPU intensive. Other UIKit methods like animateWithDuration: are executed on the GPU.
  8. Subclassing UIView to create a progress view Overriding drawRect should

    only be done as a last resort because it’s CPU intensive. Other UIKit methods like ‘animateWithDuration:’ have a pre-defined set of instructions and thus can be offloaded to the GPU. Think of the CPU as a human chef and the GPU as a blender. The chef is smarter but when it comes to one specific thing - chopping stuff up - the blender is better.
  9. Subclassing UIView to create a progress view Look at drawRect:

    in MSProgressView.m for a line-by-line explanation of how we added a gradient to our progress view
  10. Inserting and deleting rows on a table view Let’s refactor

    deleteButtonTappedFromCell: in favorites controller for a much better user experience. Everything in between beginUpdates and endUpdates is animated. Here we animate the removing of a cell from our table.
  11. Inserting and deleting rows on a table view Use caution

    when adding/deleting rows yourself. beginUpdates and endUpdates trigger some dataSource delegate methods. But other critical methods like cellForRowAtIndexPath are not called. Because of this we must force the table to reload. If you don’t call reloadData, you’ll crash upon removing the last cell.
  12. Inserting and deleting rows on a table view We must

    call reload data in a block. Calling it immediately will preempt the row animation. This is also a good place to notify the settings controller as we’re sure that the datasource is updated.
  13. Implementing the Settings Controller We will allow users to configure

    3 settings in a grouped table view 1) Set app theme color 2) Set the range of distances to show on our map and locations table 3) Move cells to order the types on our favorites table This will be our most complicated controller and the culmination of everything we’ve thus learned.
  14. Grouped table views So far we’ve used only the default

    table view setup. For favorites we’ll set the table to UITableViewStyleGrouped and use the section property of our indexPaths to organize different groups for each setting. Your phone’s Settings app is the most familiar example of a grouped table layout.
  15. MVC Look at the project navigator, we’ve created groups to

    better organize our file system. Model-View-Controller architecture fits nicely with the idea of our UIViewControllers as places to implement business logic - getting the model data presented on to the views. MVC is old and many iOS devs prefer a Model-View-ViewModel architecture where the business logic lives in a separate manager class that the UIViewController talks to.
  16. MVC For MapStack.. Models - MSLocation is the only one

    we used but a typical app will have several including a ‘user’ model. Views - subclasses of UIView e.g. buttons, table view cells, MKMapView, image views, labels, etc. View Controllers - persists data to the views. Controls and owns the views as well as its ‘view’ property that has been our canvas throughout.
  17. Coming full circle - the app delegate This should make

    more sense now that we’ve worked with delegates and protocols. Press your device’s home button or, on the simulator, go to Hardware > Home. applicationDidEnterBackground: here we may want to notify any networking to cancel or to save any unsaved input.