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

iCloud is hard

iCloud is hard

Talk at Tokyo iOS Meetup - February 2013

http://www.meetup.com/TokyoiOSMeetup/events/100621072/

Other Decks in Programming

Transcript

  1. Ignacio Enriquez @nacho4d • Peruvian, 28 years old. • In

    Japan for almost 10 years • Programs in objc/c/c++ for about 5 years • Previously at iA, now at GREE
  2. Agenda 1. What is iCloud? 2. How to use it

    (refresher) 3. The hard parts 4. Wrap-up
  3. Agenda 1. What is iCloud? 2. How to use it

    (refresher) 3. The hard parts 4. Wrap-up Just in case ...
  4. Agenda 1. What is iCloud? 2. How to use it

    (refresher) 3. The hard parts 4. Wrap-up The meat :-) Just in case ...
  5. 1. What is iCloud? • It is a service to

    sync your data • It is ubiquitous. • We have almost no control over it.
  6. 1. What is iCloud? • It is a service to

    sync your data • It is ubiquitous. • We have almost no control over it. Ubiquitous?
  7. 1. What is iCloud? • It is a service to

    sync your data • It is ubiquitous. • We have almost no control over it. Ubiquitous? What the heck?
  8. Ubiquitous • Basically means something (in this case the sync)

    will happen without being noticed or taken (much) care, seemlessly, transparent. • Term was first used by Xerox in 1968
  9. No much control • “it just works” means: no much

    control over it. • Librarian daemon (librariand) does the hard job. It wakes up and goes to sleep almost at the same time as our application. • We can listen to some important events. Unfortunately we cannot trigger all of them. • Not much to do when errors happen.
  10. 1. What is iCloud (cont.) • Key-Value storage: Similar to

    NSUserDefaults • CoreData storage: I haven’t used this • File Storage: Sync regular files Three manners of syncing your data:
  11. 1. What is iCloud (cont.) • Key-Value storage: Similar to

    NSUserDefaults • CoreData storage: I haven’t used this • File Storage: Sync regular files Today’s case Three manners of syncing your data:
  12. 2. How to use it • Beginning iCloud in iOS

    5 Tutorial - Ray Wenderlich. * → Very good introduction • Basically all applications needs to follow the same flow Remembering * http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1
  13. 2. How to use it • Beginning iCloud in iOS

    5 Tutorial - Ray Wenderlich. * → Very good introduction • Basically all applications needs to follow the same flow Remembering same steps :) * http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1
  14. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI }
  15. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI } How do I ...
  16. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI } How do I ... ... lter les?
  17. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI } How do I ... ... lter les? ... sort results?
  18. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI } How do I ... ... lter les? ... nd folders? ... sort results?
  19. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI } Should I stop the query? How do I ... ... lter les? ... nd folders? ... sort results?
  20. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI } Should I stop the query? How do I ... ... lter les? ... nd folders? ... sort results? etc, etc ... ?
  21. Very basic Steps // 1. Prepare metadata query query =

    [[NSMetadataQuery alloc] init]; [query setSearchScopes:@{NSMetadataQueryUbiquitousDocumentsScope}]; [query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemPathKey]]; // 2. Start listen for appropiate events // NSMetadataQueryDidFinishGatheringNotification, etc ... // 3. Finally start the query [query startQuery]; - (void)queryDidFinishGathering:(NSNotification *)noti { // Received event so update the UI } Should I stop the query? How do I ... ... lter les? ... nd folders? ... sort results? etc, etc ... ? ... keep my data and UI in sync?
  22. Filtering results (1) • You want: A list files and

    folders inside “myFolder” folder. • The situation: iCloud does not return folders!. It syncs them but they are not part of results. Results only contains regular files. • A solution: Find all files that has “/myFolder/” in the path and deduce the file/folder structure from there. 1
  23. Filtering results (2) • You want: A list files that

    satisficy several conditions. • Situation: NSMetadataQuery only support the simplest form of NSPredicates. Does not support NSCompoundPredicate, NSComparisonDelegate • A solution: Find all files and filter the results by your own. Not a big deal, you think ... 2
  24. Sorting results • You want: A list files get to

    be sorted as you desire • Situation: NSMetadataQuery is buggy (at least as of 6.0.1) [query setSortDescriptors:...]; does nothing! • A solution: Find all files and sort the results manually. Again, not a big deal, you think ... 3
  25. Download percentage • You want: Show a progress bar for

    each downloading file • You do: [fileURL getResourceValue:&percentage forKey:NSURLUbiquitousItemPercentDownloadedKey error:&tempError] • Situation: iOS4: Does nothing. iOS5: super slow, and is still buggy, fails frecuently. iOS6, finally deprecated! • Solution: Cache your metadata query, use its results! 4
  26. Show a file browser like OSX • You want: UI

    to show your documents • Situation: Maintaing UI and data in sync requires a really well designed application. Apple has not brought a solution for this in iOS yet. • Solution: Do it yourself. NSMetadataQuery + KVO results 5
  27. Show a file browser like OSX • You want: UI

    to show your documents • Situation: Maintaing UI and data in sync requires a really well designed application. Apple has not brought a solution for this in iOS yet. • Solution: Do it yourself. NSMetadataQuery + KVO results 5 ... but consider other approaches rst
  28. NSMetadataQuery results + KVO • So far you’ve probably been

    re-filtering, sorting, modifying raw results array in (for example) NSMetadataQueryDidFinishGatheringNotification to get your own modified results array • Problem: When raw results array has changes, you are informed of the index of the object that has changed. So you need to find a way to map this given index into your modified results array. - Depending on your structure this could get complicated ... aaargh!
  29. NSMetadataQuery results + KVO • So far you’ve probably been

    re-filtering, sorting, modifying raw results array in (for example) NSMetadataQueryDidFinishGatheringNotification to get your own modified results array • Problem: When raw results array has changes, you are informed of the index of the object that has changed. So you need to find a way to map this given index into your modified results array. - Depending on your structure this could get complicated ... aaargh! ... I told you!
  30. Solve conflicts • You want: Show an nice UI element

    to solve your files conflicts as OSX. • Situation: No built in solution for this in iOS. • Solution: Do it yourself. Not so hard but if this is not so hard why Apple does not do it? Probably because in OSX this is controlled by NSDocument and its cousin UIDocument is not even close to it. 6
  31. Search in other thread • You want: NSMetadataQuery search can

    be slow so you want to start it in the background. • Situation: [query startQuery]; only works in the main thread • A solution: Not ideal but start it in the main thread and change to a secondary thread each time you receive a notification to do additional hard-work. 7
  32. 4. Wrap-up • If you are planning to adopt iCloud,

    I would recommend you require iOS6 and above. • Spend as much time as you can reading official docs on the APIs and programming guides. • If you need UI for your file browser, consider using an open source solution or wait a bit for iOS7 before writing your own from scratch.