Weitere ähnliche Inhalte Ähnlich wie Beginning icloud development - Cesare Rocchi - WhyMCA (20) Kürzlich hochgeladen (20) Beginning icloud development - Cesare Rocchi - WhyMCA11. 1 of the Wenderlich’s
raywenderlich.com
13. ARC GameCenter API
Storyboards
News Stand
iCloud
Turn Based Gaming OpenGL ES 2.0
18. UIDocument
Key-Value store
Conflict
Resolution
CoreData
Custom
Documents
www.icloudfordevelopers.com
28. Cons (for devs)
Stick to a synch model
No http API
No control on upload
46. @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;
}
51. @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 {
}
54. #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
56. - (void)loadDocument {
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
_query = query;
[query setSearchScopes:[NSArray arrayWithObject:
NSMetadataQueryUbiquitousDocumentsScope]];
}
57. - (void)loadDocument {
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
_query = query;
[query setSearchScopes:[NSArray arrayWithObject:
NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *pred = [NSPredicate predicateWithFormat:
@"%K == %@",
NSMetadataItemFSNameKey, kFILENAME];
[query setPredicate:pred];
}
58. - (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];
}
59. NSPredicate *pred = [NSPredicate predicateWithFormat:
@"%K like 'Note_*'",
NSMetadataItemFSNameKey];
61. - (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];
}
62. - (void)loadData:(NSMetadataQuery *)query {
if ([query resultCount] == 1) {
NSMetadataItem *item = [query resultAtIndex:0];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
SMNote *doc = [[SMNote alloc] initWithFileURL:url];
}
}
63. - (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");
}
}];
}
}
64. else {
NSURL *ubiq = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
NSURL *ubiquitousPackage =
[[ubiq URLByAppendingPathComponent: @"Documents"]
URLByAppendingPathComponent:kFILENAME];
SMNote *doc = [[SMNote alloc]
initWithFileURL:ubiquitousPackage];
}
65. 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");
}];
}
}];
}
68. - (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;
}
70. - (NSURL *) localNotesURL {
return [[[NSFileManager defaultManager]
URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
}
- (NSURL *) ubiquitousNotesURL {
return [[[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil]
URLByAppendingPathComponent:@"Documents"];
}
71. - (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!
72. - (void) startMigration {
NSOperationQueue *iCloudQueue = [NSOperationQueue new];
NSInvocationOperation *op =
[[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(setNoteUbiquity)
object:nil];
[iCloudQueue addOperation:op];
}
75. @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
78. - (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];
}
79. - (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;
}
80. - (BOOL)loadFromContents:(id)contents
ofType:(NSString *)typeName
error:(NSError **)outError {
NSFileWrapper *wrapper = (NSFileWrapper *)contents;
NSDictionary *d = [wrapper fileWrappers];
NSFileWrapper *entriesWrap = [d objectForKey:@"notes.dat"];
}
81. - (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
}
87. - (void) saveNoteAsCurrent {
[[NSUbiquitousKeyValueStore defaultStore]
setString:self.currentNote.noteId
forKey:@"com.studiomagnolia.currentNote"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
}
88. - (void) saveNoteAsCurrent {
[[NSUbiquitousKeyValueStore defaultStore]
setString:self.currentNote.noteId
forKey:@"com.studiomagnolia.currentNote"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
}
NSString *currentNoteId =
[[NSUbiquitousKeyValueStore defaultStore] stringForKey:
@"com.studiomagnolia.currentNote"];
89. NSUbiquitousKeyValueStore* store =
[NSUbiquitousKeyValueStore defaultStore];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(updateCurrentNoteIfNeeded:)
name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
object:store];
[store synchronize];
95. 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;
}
99. NSError *err;
NSURL *url = [[NSFileManager defaultManager]
URLForPublishingUbiquitousItemAtURL:[self.currentNote fileURL]
expirationDate:&expirationInOneHourSinceNow
error:&err];
111. // 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;
}
112. // 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;
}
121. PFObject *note = [PFObject objectWithClassName:@"Note"];
[note setObject:@"Ciao"
forKey:@"title"];
[note setObject:@"Note on Parse"
forKey:@"content"];
[note save];
//[note saveInBackground];
//[note saveEventually];
124. 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
125. 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];
127. “You can’t always get what
you want
but if you try sometime, you
just might find ...”
128. “You can’t always get what
you want
but if you try sometime, you
just might find ...”
Rolling Stones