On my first attempt at adding iCloud to my existing app this is how far I've gotten. For reasons that I won't go into, the use case for my app does not need coordination. I have successfully made my app write a file to the Documents directory of iCloud and read back that same file without errors. In testing on a real iPhone 13 and iPhone 7 I have verified that my app can write a file to iCloud from the iPhone 7 and then read back that same file on the iPhone 13, so I know that the file truly exists in the cloud. But when I make my app on the iPhone 13 write to iCloud, my app on the iPhone 7 says the file does not exist. Exactly the same build of my app is running in both phones. This is problem #1. Problem #2 is that none of these files appear in the iCloud section of the Files app on either of these Phones, nor do they appear in the iCloud section of my Mac. All devices are signed in to my same Apple account in iCloud. Also my info.plist file in the app contains:
<key>NSUbiquitousContainers</key>
<dict>
<dict>
<key>iCloud.com.{my domain}.{my app}</key>
<dict>
<key>NSUbiquitousContainerIsDocumentScopePublic</key>
<true/>
<key>NSUbiquitousContainerSupportedFolderLevels</key>
<string>Any</string>
<key>NSUbiquitousContainerName</key>
<string>{my app}</string>
</dict>
</dict>
</dict>
<key>UIFileSharingEnabled</key><true/>
The iPhone 7 is running iOS 15.8.4 and the iPhone 13 is running iOS 18.3.2.
The code that does the writing to iCloud is:
NSFileManager *fman = [NSFileManager defaultManager];
NSURL *urlDrive = [fman URLForUbiquityContainerIdentifier: nil];
NSURL *urlDocs = [urlDrive URLByAppendingPathComponent:@"Documents"];
if(urlDocs.path == nil) {
NSLog(@"NULL path");
return; //..big problem
}
if( ! [fman fileExistsAtPath: urlDocs.path] ) { //..need to create the Docs directory
NSError *err00 = nil;
@try {
[fman createDirectoryAtURL: urlDocs withIntermediateDirectories:true
attributes:nil error:&err00];
NSLog(@"created the directory");
} @catch (NSException *except) {
NSLog(@"Exception creating directory %@", except);
}
} //..directory is now created
NSLog(@"url=%@", urlDocs);
NSURL *urlFile = [urlDocs URLByAppendingPathComponent:txtfname()];
NSData *fdata = [@"Hello world" dataUsingEncoding: NSUTF8StringEncoding];
NSLog(@"file url=%@", urlFile);
NSLog(@"file Data=%@", fdata);
NSError *errorReturn = nil;
Boolean ret = [fdata writeToURL: urlFile options: NSDataWritingAtomic error: &errorReturn];
NSLog(@"returned %1d, error=%@", ret?1:0, errorReturn);
And the code that does the reading is:
NSFileManager *fman = [NSFileManager defaultManager];
NSURL *urlDrive = [fman URLForUbiquityContainerIdentifier: nil];
NSURL *urlDocs = [urlDrive URLByAppendingPathComponent:@"Documents"];
NSLog(@"url=%@", urlDocs);
if(urlDocs.path == nil) {
NSLog(@"urlDocs.path is NULL!");
return; //..big problem
}
if( ! [fman fileExistsAtPath: urlDocs.path] ) { //..need to create the Docs directory
NSLog(@"It seems the urlDocs folder does not exist");
}
NSURL *urlFile = [urlDocs URLByAppendingPathComponent:txtfname()];
if([fman fileExistsAtPath: urlFile.path]) {
NSLog(@"file %@ exists", urlFile);
[fman copyItemAtURL: urlFile toURL:<#(nonnull NSURL *)#> error:<#(NSError *__autoreleasing _Nullable * _Nullable)#>];
} else {
NSLog(@"file %@ DOES NOT EXIST!", urlFile);
}
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
In the all the example code I see that it is recommended to keep track of the last version of your app when you called requestReviewInScene in StoreKit so that you don't call this function more than once for any particular version of your app. But I also see that the StoreKit itself enforces this requirement by only presenting the user with a request for a review once for any version of an app. So I wonder why the redundancy? When we call requestReviewInScene, the StoreKit may or may not show the user a request. Furthermore, we have no way of knowing in the code if the request was presented or not. If the request was made when the device happened to be offline (such as out of range of cell service or wi-fi or in airplane mode) then the StoreKit knows that the request was not passed along to the user, but our code does not. If we count that request and don't ever request again, the user will never see a request for a review. On the other hand, I can see some justification for limiting unnecessary internet access by not making our requests too often. How are we supposed to balance the goal of not requesting reviews too often with the goal of not wanting to miss the opportunity to request a review just because the one and only time we made our request was when the user was off-line? Would it make sense to check for internet connectivity before making our request?
Is it possible to use iCloud to backup files that are currently stored locally so that those files appear on other devices? And can this be done automatically with the user having to take explicit action to do periodic backups? I have an existing app in which the user can create local files. If I add iCloud support I do not want the users to have to move all their files to iCloud Drive first. I do not want to disrupt the current usage more than necessary.
My app uses local files to store data created by the user and I am considering integrating iCloud to facilitate syncing across devices and file sharing. Currently I use Dropbox to do that. The users of my app are sometimes out of range of any internet connection when they create data files. Will iCloud accomplish syncing automatically the next time internet connection is available, or does my app have to do something at that time when it might not even be running? Also, does iCloud document storage provide the means for the user to access these files outside of my app, say for instance, from desktop Windows, and then sent to others by email independently of the Apple infrastructure? That is what I currently do with Dropbox. Can I use iCloud to do the same thing?
Today I tried updating my Objective-C/Interface Builder based app to iOS 13, and none of my view controller transitions work anymore. Running in the Simulator, I get the error "Unbalanced calls to begin/end appearance transitions for.." followed by whatever view controller I just left. For example, if the current view controller is SettingsViewController and in response to a button press I do this:EditCustVC *vc = [[ EditCustVC alloc] init];
[nc pushViewController:vc animated:NO];Then I get the IB look of the EditCustVC, but viewDidAppear is never called for EditCustVC, and there is the error message: "Unbalanced calls to begin/end appearance transitions for SettingsViewController." Then if I dismiss EditCustVC like this:[[self navigationController] popViewControllerAnimated:NO];Then I return to the SettingsViewController, but without effect of viewDidAppear, and there is the error message: "Unbalanced calls to begin/end appearance transitions for EditCustVC." So the error message always refers to the view controller I am leaving, whether it is navigating forward with a pushViewController, or backward with a popViewController.This may be a clue: When setting breakpoints in my main view controller (which is lauched from a Nib), the sequence of calls is:awakeFromNibviewWillDisappearviewDidLoadviewWillAppearand viewDidAppear is never called. In view of the error message, the calling of viewWillDisappear before the view has appeared is highly suspicious. I should mention that this app is very complex and has been maintained since 2009 when I first released it. Many things have been added over the years, but the basic structure of launching the main view controller from a Nib, and then launching other view controllers and poping them as outlined above has never changed. It worked perfectly under iOS 12 and Xcode 10. But now that I have updated to Xcode 11 and the iOS 13 SDK, the expected sequence of calls just does not happen anymore. Since the app is quite complex at this point, it is really not feasible to totally overhaul the foundation of the app. I am looking for a minimal change that will work with the iOS 13 SDK, and still work with a deployment target of iOS 9. Does anyone have any suggestions?It is also noteable that none of these problems result in crash as such. The program continues to run - after a fashion. It is just that the messed up order of calls and the absense of calls to viewDidAppear is making the app unusable. I will also note that when I select a simulator target with iOS 12, it runs perfectly.
I have an expensive app ($300) that my users depend on for their daily work. I would like to have some of those users Flight Test an update I have prepared. But I don't want to erase the private data that the current production version has stored for each of them. Can they safely use TestFlight to load the beta version of my app without losing the data currently associated with the production version? And can they easily dump the beta version and return to the production version without losing that data? I know that if they uninstall the production version first, the private data store and settings they had developed on the production version will be lost. So I want to ensure that my testers will be able to test the beta version the same as if they had updated from the app store, in which case the private data for the app would be preserved.