Usually, my code is ok to download the files from iCloud. But sometimes the downloading process will not be updated.
Following are some code snips:
start download:
NSFileManager* fm = [NSFileManager defaultManager];
if (![fm startDownloadingUbiquitousItemAtURL:file error:nil]) {
return NO;
}
/////////////////////////
id query = [[icloudClass alloc] init];
_query = query;
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSArray *listItems = [[file path] componentsSeparatedByString:#"/"];
NSPredicate *pred = [NSPredicate predicateWithFormat: #"%K == %#", NSMetadataItemFSNameKey, [listItems objectAtIndex:[listItems count] -1] ];
NSLog(#"filename = %#", [listItems objectAtIndex:[listItems count] -1]);
[query setPredicate:pred];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateDownloading:) name:NSMetadataQueryDidUpdateNotification object:query];
[query startQuery];
update download:
-(void)updateDownloading:(NSNotification *)notification {
id query = [notification object];
if ([query resultCount] /*>=*/ == 1) {
for (int i=0; i<[query resultCount]; ++i) {
NSMetadataItem *item = [query resultAtIndex:i];
//debug
NSNumber* isDownloading = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadingKey];
NSNumber* isDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey];
NSNumber* perDownloading = [item valueForAttribute:NSMetadataUbiquitousItemPercentDownloadedKey];
NSLog(#"isDownloaded=%#", [isDownloaded boolValue]?#"Yes":#"No");
NSLog(#"isDownloading=%#", [isDownloading boolValue]?#"Yes":#"No");
NSLog(#"percent downloaded=%f", [perDownloading doubleValue]);
//
if ([isDownloaded boolValue]) {
[query disableUpdates];
[query stopQuery];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:query];
_query = nil;
NSLog(#"----------end download!------------------");
}
}//end for
}
}
please note that the update function will only be invoked once with the following console print, and never will be invoked even restart the app.
Jan 10 15:20:27 unknown *[1383] <Warning>: isHasConflict=No
Jan 10 15:20:27 unknown *[1383] <Warning>: isDownloaded=No
Jan 10 15:20:27 unknown *[1383] <Warning>: isDownloading=No
Jan 10 15:20:27 unknown *[1383] <Warning>: percent downloaded=0.000000
Does anyone met this problem before?
Related
I'm attempting to sync Core Data among devices using iCloud (using the new iOS7 method). I'm still seeing issues with the syncing when testing with the simulators. Sometimes data from one simulator won't sync to another simulator. What could ever be the problem? Here's most of the code from the AppDelegate.m:
NSManagedObjectContext *context = [self managedObjectContext];
if (!context)
[self displayAlert];
rvc.managedObjectContext = context;
The main code:
#pragma mark -
#pragma mark Core Data stack
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
*/
- (NSManagedObjectContext *)managedObjectContext {
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc performBlockAndWait:^{
[moc setPersistentStoreCoordinator: coordinator];
if(!isOldVersion){
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(storesWillChange:) name:NSPersistentStoreCoordinatorStoresWillChangeNotification object:coordinator];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(storesDidChange:) name:NSPersistentStoreCoordinatorStoresDidChangeNotification object:coordinator];
[moc setMergePolicy:[[NSMergePolicy alloc] initWithMergeType:NSMergeByPropertyObjectTrumpMergePolicy]];
}
}];
__managedObjectContext = moc;
}
return __managedObjectContext;
}
- (void)storesWillChange:(NSNotification *)notification {
if (__managedObjectContext) {
[__managedObjectContext performBlockAndWait:^{
if ([__managedObjectContext hasChanges]) {
NSError *error = nil;
[__managedObjectContext save:&error];
}
[__managedObjectContext reset];
}];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:#"SCEmptyClips" object:self userInfo:nil];
});
}
}
-(void)storesDidChange:(NSNotification *)n{
[[NSNotificationCenter defaultCenter] postNotificationName:#"SCDataChange" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:#"SCPBUpdateCheck"]];
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
*/
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil){
return __persistentStoreCoordinator;
}
firstPost = NO;
NSLog(#"STARTING to configure iCloud / new persistent store");
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"SmartCopy.sqlite"]];
NSDictionary *options;
if(!isOldVersion && [[userDefaults valueForKey:#"SCiCloudMode"] boolValue]){
options = #{NSPersistentStoreUbiquitousContentNameKey: #"MYStoreName"};
}else if(!isOldVersion){
options = #{NSPersistentStoreRemoveUbiquitousMetadataOption: #YES};
}else{
options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
}
[__persistentStoreCoordinator lock];
result = [__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:nil];
if (!result)
[self displayAlert];
[__persistentStoreCoordinator unlock];
NSLog(#"Persistent store added. Now **%u** store(s)", [[[self persistentStoreCoordinator] persistentStores] count]);
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:#"SCDataChange" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:#"SCPBUpdateCheck"]];
firstPost = YES;
});
return __persistentStoreCoordinator;
}
- (void)mergeChangesFrom_iCloud:(NSNotification *)notification {
NSLog(#"iCloud actual import");
NSLog(#"insert %#", [[notification userInfo] valueForKey:#"inserted"]);
NSLog(#"delete %#", [[notification userInfo] valueForKey:#"deleted"]);
NSLog(#"update %#", [[notification userInfo] valueForKey:#"updated"]);
[__managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
[[NSNotificationCenter defaultCenter] postNotificationName:#"SCDataChange" object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:#"SCPBUpdateCheck"]];
}
#pragma mark -
#pragma mark Application's documents directory
/**
Returns the path to the application's documents directory.
*/
- (NSString *)applicationDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
Does anything there look wrong?
Here is how I do it. It might be an easy way to simplify and unclutter your code.
self.managedObjectContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSMainQueueConcurrencyType];
self.managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
self.managedObjectContext.persistentStoreCoordinator =
[[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:self.managedObjectModel];
[self.managedObjectContext.persistentStoreCoordinator
addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.storeURL
options:#{ NSPersistentStoreUbiquitousContentNameKey : #"iCloudStore" }
error:&error];
The only iCloud bit is the options parameter. (I removed other options for clarity.) The store URL is just [documentsDirectory URLByAppendingPathComponent:#"Store.sqlite"].
I am also listening to these:
NSPersistentStoreDidImportUbiquitousContentChangesNotification
NSPersistentStoreCoordinatorStoresWillChangeNotification
NSPersistentStoreCoordinatorStoresDidChangeNotification
In the first one, I call
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:note];
and post another notification to update the UI; in the second one, I save; in the third one I also update the UI.
For me that's really all there is to it. It works flawlessly up to now.
Credit goes to iCloudCoreDataStack.
I added some events to the calendar and save their eventIdentifier to file. When i want to remove all my events i read the eventIdentifier from that file to an array and remove each event with its event id. Here is the code to add event to calendar and save their event id to file:
- (void) addEventToCalendar: (id)object
{
#autoreleasepool {
int i = 0;
NSString *string_to_file = #"";
eventStore=[[EKEventStore alloc] init];
for(Schedule *sche in scheduleArray){
EKEvent *addEvent=[EKEvent eventWithEventStore:eventStore];
addEvent.title=sche.course_Name;
addEvent.startDate = [self stringToDate:sche.from_Date];
addEvent.endDate = [self stringToDate:sche.thru_Date];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[addEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
NSDate *date_alarm = [addEvent.startDate dateByAddingTimeInterval:-(10*60)];
addEvent.alarms=[NSArray arrayWithObject:[EKAlarm alarmWithAbsoluteDate:date_alarm]];
NSError *err;
// do save event to calendar
[eventStore saveEvent:addEvent span:EKSpanThisEvent error:&err];
if (err == nil) {
NSString* str = [[NSString alloc] initWithFormat:#"%#", addEvent.eventIdentifier];
string_to_file = [string_to_file stringByAppendingString:str];
string_to_file = [string_to_file stringByAppendingString:#"\n"];
NSLog(#"String %d: %#",i, str);
}
else {
NSLog(#"Error %#",err);
}
i++;
}
// create file to save
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
inFile = [NSFileHandle fileHandleForWritingAtPath: filePath];
NSData *data = [string_to_file dataUsingEncoding:NSUTF16StringEncoding];
[inFile writeData:data];
}
}
And the code below to remove all events i have added to calendar
- (void) deleteEventInCalender {
filemgr = [NSFileManager defaultManager];
NSString *filePath = [self getFilePath:#"saveeventid.txt"];
NSFileHandle *inFile;
inFile = [NSFileHandle fileHandleForReadingAtPath:filePath];
NSData *dataFile;
dataFile = [inFile readDataToEndOfFile];
NSString *tmp = #"";
NSString *temp = #"";
tmp = [NSString stringWithCharacters:[dataFile bytes] length:[dataFile length]/sizeof(unichar)];
if(![tmp isEqualToString:#""]){
tmp = [tmp substringFromIndex:1];
event_idArray = [[NSMutableArray alloc] init];
int j = 0;
while (![tmp isEqualToString:#""]){
int index_find_string = [tmp rangeOfString:#"\n"].location;
temp = [tmp substringWithRange:NSMakeRange(0, index_find_string)];
[event_idArray addObject:temp];
tmp = [tmp substringFromIndex:index_find_string + 1];
}
EKEventStore* store = [[EKEventStore alloc] init];
j = 0;
for(NSString *eventid in event_idArray){
EKEvent* event2 = [store eventWithIdentifier:eventid];
if (event2 != nil) {
NSLog(#"log: %d log id: %#", j, eventid);
NSError* error = nil;
// remove event
[store removeEvent:event2 span:EKSpanThisEvent error:&error];
}
j++;
}
[filemgr removeItemAtPath:filePath error:nil];
}
}
All codes above work well when i test on the iOS simulator with calendar.sqlitedb. But it makes some strange errors when i run on iPad device 5.0. That is sometime the calendar not remove event or when all events has been remove then after some minutes all events appear again... I don't understand, i don't know why and i very confuse. Does anyone has the same issue with me? Please share your solution!
Added another question: where the calendar database stored in the iOS 5.0 device.
I've been looking at getting Core Data working with iCloud so peoples data is accessible from multiple devices.
I've been following this tutorial (http://timroadley.com/) best as possible with chugging my app, but i've ran into a few issues.
Issue 1: When the app is closed (not just suspended) and reopened there is nothing showing in the table, so the previous data doesn't seem to get loaded
Issue 2: I don't know if its iCloud or the app, but it takes age to sync the changes. I make a change on one device, its takes 2-3 minutes to show on the other
Can anyone help me solve these two issues please
This code is in my AppDelegate
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if((__persistentStoreCoordinator != nil)) {
return __persistentStoreCoordinator;
}
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;
// Set up iCloud in another thread:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ** Note: if you adapt this code for your own use, you MUST change this variable:
NSString *iCloudEnabledAppID = #"MF4HVVX5DS.Desbrina.Medicine-Tracker";
// ** Note: if you adapt this code for your own use, you should change this variable:
NSString *dataFileName = #"Medicine-Tracker.sqlite";
// ** Note: For basic usage you shouldn't need to change anything else
NSString *iCloudDataDirectoryName = #"Data.nosync";
NSString *iCloudLogsDirectoryName = #"Logs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud) {
NSLog(#"iCloud is working");
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
NSLog(#"iCloudEnabledAppID = %#",iCloudEnabledAppID);
NSLog(#"dataFileName = %#", dataFileName);
NSLog(#"iCloudDataDirectoryName = %#", iCloudDataDirectoryName);
NSLog(#"iCloudLogsDirectoryName = %#", iCloudLogsDirectoryName);
NSLog(#"iCloud = %#", iCloud);
NSLog(#"iCloudLogsPath = %#", iCloudLogsPath);
if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if(fileSystemError != nil) {
NSLog(#"Error creating database directory %#", fileSystemError);
}
}
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
NSLog(#"iCloudData = %#", iCloudData);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:nil];
[psc unlock];
}
else {
NSLog(#"iCloud is NOT working - using a local store");
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[psc lock];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
[psc unlock];
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:#"SomethingChanged" object:self userInfo:nil];
});
});
return __persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc performBlockAndWait:^{
[moc setPersistentStoreCoordinator: coordinator];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
}];
__managedObjectContext = moc;
}
return __managedObjectContext;
}
- (void)mergeChangesFrom_iCloud:(NSNotification *)notification {
NSLog(#"Merging in changes from iCloud...");
NSManagedObjectContext* moc = [self managedObjectContext];
[moc performBlock:^{
[moc mergeChangesFromContextDidSaveNotification:notification];
NSNotification* refreshNotification = [NSNotification notificationWithName:#"SomethingChanged"
object:self
userInfo:[notification userInfo]];
[[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
}];
}
and this is in the master view controller
- (void)reloadFetchedResults:(NSNotification*)note {
NSLog(#"Underlying data changed ... refreshing!");
[self fetchedResultsController];
NSLog(#"%#", note.object);
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reloadFetchedResults:)
name:#"SomethingChanged"
object:[[UIApplication sharedApplication] delegate]];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Issue 1: When the app is closed (not just suspended) and reopened there is nothing showing in the table, so the previous data doesn't seem to get loaded
check that you save all data to your managed object context. This should not be Core Data issue
Issue 2: I don't know if its iCloud or the app, but it takes age to sync the changes. I make a change on one device, its takes 2-3 minutes to show on the other
2-3 minutes is really fine. It can sometimes take hours to get data in fully synced state. At least I experienced this half a year ago.
Bear in mind that iCloud is not suited for simultaneous use on several devices. It rather offers something like eventual consistency.
in your example:
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
use your
NSString *iCloudEnabledAppID = #"MF4HVVX5DS.Desbrina.Medicine-Tracker";
as URLForUbiquityContainerIdentifier
it should be like that:
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier: iCloudEnabledAppID];
I'm new to iPhone Development.
I have integrated iCloud storage in my application. I am successful in uploading documents on iCloud.
My document's size is around 126799 bytes. During uploading on iCloud I have made sure that a proper document is uploaded on iCloud by printing its length and content on the console. But when I am fetching document from iCloud it only gives me 3/4 of the content of that document. I have also checked this on console by printing its length and content.
/////====== variables are declared in interface file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *ubiq = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
if (ubiq)
{
NSLog(#"iCloud access at %#", ubiq);
// TODO: Load document...
[self loadDocument];
}
else
{
NSLog(#"No iCloud access");
}
}
- (void)loadDocument{
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
_query = query;
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSString *filename = #"supplimentlistdescription.txt";
NSPredicate *pred = [NSPredicate predicateWithFormat:#"%K like '%#'",filename,NSMetadataItemFSNameKey];
[query setPredicate:pred];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(queryDidFinishGathering:)
name:NSMetadataQueryDidFinishGatheringNotification
object:query];
[query startQuery];
}
- (void)queryDidFinishGathering:(NSNotification *)notification {
NSMetadataQuery *query = [notification object];
[query disableUpdates];
[query stopQuery];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSMetadataQueryDidFinishGatheringNotification
object:query];
_query = nil;
[self loadData:query];
}
- (void)loadData:(NSMetadataQuery *)query {
if ([query resultCount] == 1)
{
NSMetadataItem *item = [query resultAtIndex:0];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
Note *doc = [[Note alloc] initWithFileURL:url];
self.doc = doc;
[self.doc openWithCompletionHandler:^(BOOL success)
{
if (success)
{
NSLog(#"iCloud document opened");
}
else
{
NSLog(#"failed opening document from iCloud");
}
}
];
}
else
{
NSFileManager *filemgr = [NSFileManager defaultManager];
NSString *fileurlstring = [NSString stringWithFormat:#"Documents/Federal Rules of Civil Procedure"];
NSLog(#"fileurlstring:%#",fileurlstring);
ubiquityURL = [[filemgr URLForUbiquityContainerIdentifier:nil]
URLByAppendingPathComponent:fileurlstring];
[ubiquityURL retain];
NSLog(#"ubiquityURL1:%#",ubiquityURL);
if ([filemgr fileExistsAtPath:[ubiquityURL path]] == NO)
{
[ubiquityURL retain];
[filemgr createDirectoryAtURL:ubiquityURL withIntermediateDirectories:YES attributes:nil error:nil];
[ubiquityURL retain];
}
ubiquityURL = [ubiquityURL URLByAppendingPathComponent:#"supplimentlistdescription.txt"];
[ubiquityURL retain];
NSLog(#"ubiquityURL:%#",ubiquityURL);
Note *doc = [[Note alloc] initWithFileURL:ubiquityURL];
self.doc = doc;
[doc saveToURL:[doc fileURL]
forSaveOperation:UIDocumentSaveForCreating
completionHandler:^(BOOL success)
{
if (success) {
[doc openWithCompletionHandler:^(BOOL success)
{
NSLog(#"new document opened from iCloud");
}
];
}
}
];
}
}
-
///Note.h
#import <UIKit/UIKit.h>
#interface Note : UIDocument
#property (strong) NSString * noteContent;
#end
-
#import "Note.h"
#implementation Note
#synthesize noteContent;
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName
error:(NSError **)outError
{
if ([contents length] > 0)
{
self.noteContent = [[NSString alloc]
initWithBytes:[contents bytes]
length:[contents length]
encoding:NSUTF8StringEncoding];
NSLog(#"loadFromContents1");
NSLog(#"noteContent:%#",noteContent);
NSLog(#"noteContent.length:%d",noteContent.length);
}
else
{
// When the note is first created, assign some default content
self.noteContent = #"Empty";
}
return YES;
}
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
if ([self.noteContent length] == 0)
{
//self.noteContent = #"Empty";
NSString *FolderName = #"Federal Rules of Civil Procedure";
NSString *fileName = #"supplimentlistdescription.txt";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[FolderName retain];
NSString *fileName1 = [NSString stringWithFormat:#"%#/%#/%#",documentsDirectory,FolderName, fileName];
NSLog(#"fileName1:%#",fileName1);
NSData *data = [[NSData alloc]initWithContentsOfFile:fileName1];
noteContent =[[NSString alloc]initWithData:data encoding:NSMacOSRomanStringEncoding];
NSLog(#"noteContent:%#",noteContent);
NSLog(#"noteContent.length:%d",noteContent.length);
}
return [NSData dataWithBytes:[self.noteContent UTF8String]
length:[self.noteContent length]];
}
#end
Can you please tell me whats can be the problem? Any suggestion will be appreciated. Thanks
I got a same problem like your before.
You should use
for writing
[self.noteContent dataUsingEncoding:NSUTF8StringEncoding];
for reading
self.noteContent = [[NSString alloc] initWithData:contents encoding:NSUTF8StringEncoding];
Example :
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError
{
if ([contents length] > 0) {
self.noteContent = [[NSString alloc] initWithData:contents encoding:NSUTF8StringEncoding];
} else {
self.noteContent = #""; // When the note is created we assign some default content
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"noteModified"
object:self];
return YES;
}
// Called whenever the application (auto)saves the content of a note
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
if ([self.noteContent length] == 0) {
self.noteContent = #"";
}
return [self.noteContent dataUsingEncoding:NSUTF8StringEncoding];
}
I am updating my app to use iCloud and want my iOS deployment target to remain 3.2. I am conditionally shielding any iOS 5 calls to prevent any back level versions from crashing. My applicationDidFinishLaunching looks like...
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(#"Launching Began...");
navigationController = [[UINavigationController alloc] init];
navigationController.navigationBar.barStyle = UIBarStyleBlack;
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
// Getting the documentsPath.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
// Setting up the mainCarList
//unarchive the saved carlist
NSString *archivePathFilename = [documentsPath stringByAppendingString:#"/carlist.archive"];
self.mainCarList = nil;
self.mainCarList = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePathFilename] retain];
//if OS version => 5.0 then
NSString *reqSysVer = #"5.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
NSLog(#"in ApplicationDidFinishLaunching iOS version > 5.0");
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(carListDocumentStateChanged) name:#"UIDocumentStateChangedNotification" object:Nil];
NSString *carListDocumentURLString = [documentsPath stringByAppendingString:#"/mainCarListDocument.CLD"];
self.mainCarListDocumentURL = [NSURL fileURLWithPath:carListDocumentURLString]; //sets the local save location only in this property
Class cls = NSClassFromString (#"NSMetadataQuery");
if (cls) {
NSMetadataQuery *query;
query = [[NSMetadataQuery alloc] init]; // <------- This crashes when running v4.3 iPhone sim.
/*
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
[self setDocumentMetaDataQuery:query];
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDataScope]];
[query setPredicate:[NSPredicate predicateWithFormat:#"%K == %#", NSMetadataItemFSNameKey, #"mainCarListDocument.CLD"]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(queryDidFinishGathering) name:NSMetadataQueryDidFinishGatheringNotification object:Nil];
BOOL didStart = NO;
didStart = [query startQuery];
if (didStart) {
NSLog(#"documentMetaDataQuery started");
}
else {
NSLog(#"error starting documentMetaDataQuery");
}
*/
[query release];
}
...
I think something is going on at compile time since the "Launching Began" log is not posted. The conditional block works correctly. If I comment out the query's alloc init, then the block gets ran only if iOS 5 is running. Any ideas?
Replace the following code:
NSMetadataQuery *query;
query = [[NSMetadataQuery alloc] init];
By this code:
id query;
query = [[cls alloc] init];
You have to use cls instead of NSMetadataQuery.