Beginning icloud development - Cesare Rocchi - WhyMCA
-
Upload
whymca -
Category
Technology
-
view
1.504 -
download
1
Transcript of Beginning icloud development - Cesare Rocchi - WhyMCA
![Page 1: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/1.jpg)
Beginning iCloud developmentRocchi Cesare
@_funkyboy studiomagnolia.com
![Page 2: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/2.jpg)
Outline
What is iCloud?
How does it work?
Are there alternatives?
![Page 3: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/3.jpg)
Who am I?
![Page 4: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/4.jpg)
UX designer and developer
![Page 5: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/5.jpg)
mnml
![Page 6: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/6.jpg)
< is >
![Page 7: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/7.jpg)
execution matters
![Page 8: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/8.jpg)
lean approach
![Page 9: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/9.jpg)
1000 details coming together
![Page 10: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/10.jpg)
Giveaway
![Page 11: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/11.jpg)
1 of the Wenderlich’s
raywenderlich.com
![Page 12: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/12.jpg)
![Page 13: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/13.jpg)
iCloud
Storyboards
ARC
OpenGL ES 2.0
News Stand
Turn Based Gaming
GameCenter API
![Page 15: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/15.jpg)
Giveaway
![Page 16: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/16.jpg)
Giveaway(yes, another)
![Page 18: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/18.jpg)
www.icloudfordevelopers.com
Conflict Resolution
CoreData
UIDocument
Key-Value store
Custom Documents
![Page 20: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/20.jpg)
Who are you?
![Page 21: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/21.jpg)
What is iCloud?
![Page 22: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/22.jpg)
6028 Startown Rd, Maiden, NC
![Page 23: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/23.jpg)
Stores and synchs stuff
![Page 24: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/24.jpg)
It just works ...
![Page 25: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/25.jpg)
... when it works
![Page 26: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/26.jpg)
Seamlessness can be a limit
![Page 27: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/27.jpg)
Pros (for devs)
No server setup
No costs
No rumination on synch
![Page 28: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/28.jpg)
Cons (for devs)
Stick to a synch model
No http API
No control on upload
![Page 29: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/29.jpg)
Pros and Cons for users
Expectation
![Page 30: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/30.jpg)
Under the hood
![Page 31: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/31.jpg)
![Page 32: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/32.jpg)
Daemon
Monitors changes
Works on metadata
Shreds files
![Page 33: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/33.jpg)
Special folder, synched
![Page 34: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/34.jpg)
Synched when “appropriate”
![Page 35: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/35.jpg)
Appropriate
Which OS?
Which connection?
Battery status?
![Page 36: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/36.jpg)
Placeholders
![Page 37: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/37.jpg)
![Page 38: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/38.jpg)
![Page 39: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/39.jpg)
Information Structure
Document
Key-value
CoreData
![Page 40: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/40.jpg)
UIDocument
![Page 41: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/41.jpg)
UIDocument
NSFilePresenter
Non-blocking read/write
![Page 42: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/42.jpg)
![Page 43: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/43.jpg)
-(void) openWithCompletionHandler:^(BOOL success) { }
![Page 44: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/44.jpg)
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError { }
![Page 45: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/45.jpg)
@interface SMNote : UIDocument
![Page 46: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/46.jpg)
@implementation SMNote
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError {
if ([contents length] > 0) { self.myContent = [[NSString alloc] initWithBytes:[contents bytes] length:[contents length] encoding:NSUTF8StringEncoding]; } else {
// Default content self.myContent = @"Empty";
} return YES; }
![Page 47: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/47.jpg)
- (BOOL) saveToURL:(NSURL *)url forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) { }
![Page 48: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/48.jpg)
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError {}
![Page 49: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/49.jpg)
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError { return [NSData dataWithBytes:[self.myContent UTF8String] length:[self.myContent length]];
}
![Page 50: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/50.jpg)
Autosave
updateChangeCount:
use the methods of the undoManager
![Page 51: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/51.jpg)
@implementation SMNote
@synthesize noteContent;
// Called whenever the application reads data - (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError { }
// Called whenever the application (auto)saves the content - (id)contentsForType:(NSString *)typeName error:(NSError **)outError { }
![Page 52: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/52.jpg)
Opening a document
![Page 53: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/53.jpg)
Opening a document
Build and run a query
Wait for results
Unfold results
![Page 54: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/54.jpg)
#import "SMNote.h"
@interface SMAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;@property (strong, nonatomic) SMViewController *viewController;
@property (strong) SMNote *doc;@property (strong) NSMetadataQuery *query;
- (void)loadDocument;
@end
![Page 55: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/55.jpg)
NSMetadataQuery
![Page 56: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/56.jpg)
- (void)loadDocument { NSMetadataQuery *query = [[NSMetadataQuery alloc] init]; _query = query;
[query setSearchScopes:[NSArray arrayWithObject: NSMetadataQueryUbiquitousDocumentsScope]]; }
![Page 57: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/57.jpg)
- (void)loadDocument { NSMetadataQuery *query = [[NSMetadataQuery alloc] init]; _query = query;
[query setSearchScopes:[NSArray arrayWithObject: NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K == %@",
NSMetadataItemFSNameKey, kFILENAME];
[query setPredicate:pred]; }
![Page 58: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/58.jpg)
- (void)loadDocument { NSMetadataQuery *query = [[NSMetadataQuery alloc] init]; _query = query;
[query setSearchScopes:[NSArray arrayWithObject: NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K == %@",
NSMetadataItemFSNameKey, kFILENAME];
[query setPredicate:pred];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(queryDidFinish:) name:NSMetadataQueryDidFinishGatheringNotification
object:query]; [query startQuery]; }
![Page 59: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/59.jpg)
NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K like 'Note_*'", NSMetadataItemFSNameKey];
![Page 60: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/60.jpg)
Asynchronous!
![Page 61: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/61.jpg)
- (void)queryDidFinish:(NSNotification *)notification { NSMetadataQuery *query = [notification object]; [query disableUpdates]; [query stopQuery]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query]; _query = nil; ! [self loadData:query]; }
![Page 62: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/62.jpg)
- (void)loadData:(NSMetadataQuery *)query { if ([query resultCount] == 1) {
NSMetadataItem *item = [query resultAtIndex:0]; NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
SMNote *doc = [[SMNote alloc] initWithFileURL:url];
}
}
![Page 63: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/63.jpg)
- (void)loadData:(NSMetadataQuery *)query { if ([query resultCount] == 1) {
NSMetadataItem *item = [query resultAtIndex:0]; NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
self.doc = [[SMNote alloc] initWithFileURL:url];
[self.doc openWithCompletionHandler:^(BOOL success) {
if (success) { NSLog(@"iCloud document opened"); } else { NSLog(@"failed opening document from iCloud"); } }];
}
}
![Page 64: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/64.jpg)
else { NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent: @"Documents"]
URLByAppendingPathComponent:kFILENAME]; SMNote *doc = [[SMNote alloc] initWithFileURL:ubiquitousPackage]; }
![Page 65: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/65.jpg)
else { NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent: @"Documents"]
URLByAppendingPathComponent:kFILENAME]; SMNote *doc = [[SMNote alloc] initWithFileURL:ubiquitousPackage]; self.doc = doc; [doc saveToURL: [doc fileURL] forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if (success) { [doc openWithCompletionHandler:^(BOOL success) { NSLog(@"new document opened from iCloud"); }]; } }];
}
![Page 66: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/66.jpg)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
... [self.window makeKeyAndVisible]; NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (ubiq) {
NSLog(@"iCloud access at %@", ubiq); [self loadDocument];
} else {
NSLog(@"No iCloud access");
} return YES;}
![Page 67: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/67.jpg)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
... [self.window makeKeyAndVisible]; NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (ubiq) {
NSLog(@"iCloud access at %@", ubiq); [self loadDocument];
} else {
NSLog(@"No iCloud access");
} return YES;}
![Page 68: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/68.jpg)
- (void)viewDidLoad {
[super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataReloaded:) name:@"noteModified"
object:nil];}
- (void)dataReloaded:(NSNotification *)notification { self.doc = notification.object; self.noteView.text = self.doc.noteContent; }
![Page 69: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/69.jpg)
Switching on/off
![Page 70: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/70.jpg)
- (NSURL *) localNotesURL { return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; }
- (NSURL *) ubiquitousNotesURL { return [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:@"Documents"]; }
![Page 71: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/71.jpg)
- (void) setNoteUbiquity { NSURL *baseUrl = [self localNotesURL]; if (_useiCloud) baseUrl = [self ubiquitousNotesURL]; NSURL *destUrl = [baseUrl URLByAppendingPathComponent: [note.fileURL lastPathComponent]];
[[NSFileManager defaultManager] setUbiquitous:_useiCloud itemAtURL:note.fileURL destinationURL:destUrl error:NULL]; }
Don’t call it on the main thread!
![Page 72: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/72.jpg)
- (void) startMigration {
NSOperationQueue *iCloudQueue = [NSOperationQueue new]; NSInvocationOperation *op =
[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(setNoteUbiquity) object:nil];
[iCloudQueue addOperation:op]; }
![Page 73: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/73.jpg)
Custom documents
![Page 74: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/74.jpg)
SMNotesDocument
SMNote SMNote SMNote
...
![Page 75: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/75.jpg)
@interface SMNote : NSObject <NSCoding>
@property (copy, nonatomic) NSString *noteId;@property (copy, nonatomic) NSString *noteContent;@property (strong, nonatomic) NSDate *createdAt;@property (strong, nonatomic) NSDate *updatedAt;
@end
![Page 76: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/76.jpg)
#import "SMNote.h"
@interface SMNotesDocument : UIDocument
@property (nonatomic, strong) NSMutableArray *entries;@property (nonatomic, strong) NSFileWrapper *fileWrapper;
@end
![Page 77: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/77.jpg)
#import "SMNote.h"
@interface SMNotesDocument : UIDocument
@property (nonatomic, strong) NSMutableArray *entries;@property (nonatomic, strong) NSFileWrapper *fileWrapper;
@end
![Page 78: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/78.jpg)
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError {
NSMutableDictionary *w = [NSMutableDictionary dictionary]; NSMutableData *data = [NSMutableData data]; NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; [arch encodeObject:_entries forKey:@"entries"]; [arch finishEncoding]; }
![Page 79: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/79.jpg)
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError {
NSMutableDictionary *w = [NSMutableDictionary dictionary]; NSMutableData *data = [NSMutableData data]; NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; [arch encodeObject:_entries forKey:@"entries"]; [arch finishEncoding]; NSFileWrapper *entriesWrapper = [[NSFileWrapper alloc]
initRegularFileWithContents:data]; [w setObject:entriesWrapper forKey:@"notes.dat"]; // add other wrappers if you like NSFileWrapper *res = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:w]; return res; }
![Page 80: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/80.jpg)
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError { NSFileWrapper *wrapper = (NSFileWrapper *)contents; NSDictionary *d = [wrapper fileWrappers]; NSFileWrapper *entriesWrap = [d objectForKey:@"notes.dat"]; }
![Page 81: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/81.jpg)
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError { NSFileWrapper *wrapper = (NSFileWrapper *)contents; NSDictionary *d = [wrapper fileWrappers]; NSFileWrapper *entriesWrap = [d objectForKey:@"notes.dat"]; NSData *data = [entriesWrap regularFileContents]; NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; _entries = [arch decodeObjectForKey:@"entries"]; // Notify the view
}
![Page 82: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/82.jpg)
Uniform Type Identifier
![Page 83: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/83.jpg)
![Page 84: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/84.jpg)
Key-value
![Page 85: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/85.jpg)
Key-value1Mb
![Page 86: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/86.jpg)
Key-value1Mb
was 64Kb !
![Page 87: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/87.jpg)
- (void) saveNoteAsCurrent {
[[NSUbiquitousKeyValueStore defaultStore] setString:self.currentNote.noteId forKey:@"com.studiomagnolia.currentNote"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
}
![Page 88: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/88.jpg)
- (void) saveNoteAsCurrent {
[[NSUbiquitousKeyValueStore defaultStore] setString:self.currentNote.noteId forKey:@"com.studiomagnolia.currentNote"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
}
NSString *currentNoteId = [[NSUbiquitousKeyValueStore defaultStore] stringForKey: @"com.studiomagnolia.currentNote"];
![Page 89: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/89.jpg)
NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateCurrentNoteIfNeeded:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:store];
[store synchronize];
![Page 90: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/90.jpg)
Conflict Resolution
![Page 91: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/91.jpg)
Conflict Resolution
Up to the dev
documentState
![Page 92: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/92.jpg)
DocumentStates
UIDocumentStateNormal
UIDocumentStateClosed
UIDocumentStateInConflict
UIDocumentStateSavingError
UIDocumentStateEditingDisabled
![Page 93: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/93.jpg)
UIDocumentStateChangedNotification
![Page 94: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/94.jpg)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(noteHasChanged:) name:UIDocumentStateChangedNotification object:nil];
![Page 95: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/95.jpg)
UIDocumentState s = [n documentState]; switch (s) {
case UIDocumentStateNormal: NSLog(@"Everything is fine"); break;
case UIDocumentStateInConflict: NSLog(@"There is a conflict"); break;
...
default: NSLog(@"Unknown state"); break;
}
![Page 96: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/96.jpg)
UI conflict vs
iCloud conflict
![Page 97: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/97.jpg)
Resolution policy
last wins
prompt user
automatic merge
![Page 98: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/98.jpg)
Resolution policy
last wins
prompt user
automatic merge
NSFileVersion
![Page 99: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/99.jpg)
NSError *err; NSURL *url = [[NSFileManager defaultManager] URLForPublishingUbiquitousItemAtURL:[self.currentNote fileURL] expirationDate:&expirationInOneHourSinceNow error:&err];
![Page 100: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/100.jpg)
![Page 101: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/101.jpg)
Tips & Tricks
![Page 102: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/102.jpg)
Patience!
![Page 103: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/103.jpg)
Test on wireless & 3G
![Page 104: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/104.jpg)
Regenerate provisioning
![Page 105: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/105.jpg)
Delete previous data
![Page 106: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/106.jpg)
![Page 107: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/107.jpg)
Restart device
![Page 108: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/108.jpg)
API throttle!
![Page 109: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/109.jpg)
App policy
Be gentle with storage
<App_home>/tmp
<App_home>/Library/Caches/
![Page 110: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/110.jpg)
App policy
Documents is backed up
mark files as “do not backup”
![Page 111: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/111.jpg)
// iOS 5.0.1
#import <sys/xattr.h>
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL { const char* filePath = [[URL path] fileSystemRepresentation]; const char* attrName = "com.apple.MobileBackup"; u_int8_t attrValue = 1; int result = setxattr(filePath, attrName, &attrValue,
sizeof(attrValue), 0, 0); return result == 0;
}
![Page 112: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/112.jpg)
// iOS 5.1
- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL { NSError *error = nil;
BOOL success = [URL setResourceValue: [NSNumber numberWithBool:YES] forKey: NSURLIsExcludedFromBackupKey
error: &error]; if(!success){
NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error);
}
return success;}
![Page 113: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/113.jpg)
“To iCloud or not to iCloud?”
![Page 114: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/114.jpg)
Alternatives
![Page 115: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/115.jpg)
Alternatives
dropbox
parse.com
cloudmine
stackmob
custom
![Page 116: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/116.jpg)
Dropbox
documents
authentication
no notifications
![Page 117: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/117.jpg)
Dropbox
other platforms
no CR (revision #)
expectation
![Page 118: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/118.jpg)
Parse
![Page 119: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/119.jpg)
Parse
ORM approach
Recently released
No cost of infrastructure
![Page 120: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/120.jpg)
Parse
Pay as you use
Limit of calls/mo
![Page 121: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/121.jpg)
PFObject *note = [PFObject objectWithClassName:@"Note"];
[note setObject:@"Ciao" forKey:@"title"];
[note setObject:@"Note on Parse" forKey:@"content"];
[note save];//[note saveInBackground];//[note saveEventually];
![Page 122: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/122.jpg)
[note saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) { if (error) {
NSLog(@"Note not saved");
} else {
NSLog(@"Note saved successfully");
}}];
![Page 123: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/123.jpg)
Parse
Other platforms
REST API
Push notifications
Object browser
![Page 124: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/124.jpg)
curl -X POST \-H "X-Parse-Application-Id: ${APPLICATION_ID}" \-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \-H "Content-Type: application/json" \-d '{"note": 001, "title": "Ciao", "content": “Note on parse” }' \https://api.parse.com/1/classes/GameScore
![Page 125: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/125.jpg)
PFObject *note = [PFObject objectWithClassName:@"Note"];
[note setObject:@"Ciao" forKey:@"title"];
[note setObject:@"Note on parse" forKey:@"content"];
PFObject *myTag = [PFObject objectWithClassName:@"Tag"];
[myTag setObject:@"important" forKey:@"tagName"];
// Add a relation[note setObject:myTag forKey:@"tag"];
// Saves both[note saveInBackground];
![Page 126: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/126.jpg)
Recap
UIDocument
Key-Value store
Alternatives
![Page 127: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/127.jpg)
“You can’t always get what you want
but if you try sometime, you just might find ...”
![Page 128: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/128.jpg)
“You can’t always get what you want
but if you try sometime, you just might find ...”
Rolling Stones
![Page 129: Beginning icloud development - Cesare Rocchi - WhyMCA](https://reader035.fdocuments.net/reader035/viewer/2022062303/554a06c0b4c905507a8b54cc/html5/thumbnails/129.jpg)
Contact
twitter.com/_funkyboy
http://studiomagnolia.com