I've made it possible to show inserted data on other devices through iCloud, but even when I turn iCloud off for my app (Documents&Data -> My App Off), after a few seconds the entered data appears on the other device (which has iCloud enabled) also.
Does this mean that even if
- (void)initializeiCloudAccessWithCompletion:(void (^)(BOOL available)) completion {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL * _iCloudJuurkataloog = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (_iCloudJuurkataloog != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"iCloud available at: %#", _iCloudJuurkataloog);
completion(TRUE);
});
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"iCloud not available or the app is running in simulator");
completion(FALSE);
});
}
});
}
returns "iCloud not available", it is only informative message and I have to control saving to iCloud manually, because if I won't the data will be saved anyway?
Edit:
It seems that when turning iCloud off from Documents&Data under Documents&Data (I guess it turns iCloud off for all apps as it says "Allow apps to store documents and data in iCloud" for enabled mode), everything works as expected - NSUbiquityIdentityDidChangeNotification is received and I won't be able to send any data to iCloud or receive any data from iCloud.
But when turning off iCloud for specific app (Documents&Data -> My App Off), NSUbiquityIdentityDidChangeNotification is not received, URLForUbiquityContainerIdentifier returns nil as if iCloud isn't available, the app can still send updates to iCloud, BUT it won't be able to receive them.
Am I getting something wrong or is there a reason to believe that this is the Apple bug?
By the way, when toggling the iCloud switch for specific app while running from Xcode on a device, I get a SIGKILL - maybe a Xcode bug?
Related
How do I upload an image to Firebase Storage when the user terminates the app?
Here's my code:
firebaseRef.child("\(uid)/\(filePath)").put(data, metadata: metadata) { (metadata, error) in
// NOTE: This spot never reaches when user closes the app
if error != nil || metadata == nil {
log.error("Fail to store image in cloud storage")
} else {
// Do something with the metadata url
}
As you can see, the async completion block never completes if the user terminates the app and I'm not able to upload the user's image to Firebase Storage
How do I safeguard against user terminating the app after uploading the picture? I have a preliminary idea. Could I store the image in CoreData/NSUserDefaults temporarily, and retry the upload when the user opens the app again?
Good question. At present, on iOS, there's no way of persisting and restarting the upload or download if the app is backgrounded or killed. This feature exists on Android (since the Activity is reset on screen rotation, making this a far more common issue), and we're planning on making it available on iOS in the future.
Eventually, we want to simply make this a flag [FIRStorage enablePersistentUploads:YES] or similar, to automatically do this for you, so you don't have to think about it at all.
I have followed all the directions from the Facebook Developer website about integrating Facebook SDK 3.1 into iOS 6. My code runs perfectly on the iPhone 6.0 Simulator (user can log into Facebook), but when I run the app on my iPhone, the function [FBRequest requestForMe] startWithCompletionHandler] doesn't generate a response. According to the Facebook Developer website, it should either be successful or return an error, but it does neither. The app just sits there waiting for a response that never comes. My code is below:
- (void)populateUserDetails {
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(#"logged in");
} else {
NSLog(#"error: %#", error);
}
}];
} else {
NSLog(#"no active session");
}
}
Using breakpoints, I determined that the activeSession is always open, so the startWithCompletionHandler: method is actually called. Maybe it's a build problem since it runs fine on the Simulator? Any ideas?
make sure that a "0" value hasn't been inserted automatically for your App Store
ID
App Store ID is different than Bundle ID. Like it says on Facebook: "For security reasons, we check the bundle ID before authorizing your app". So you should set that exactly as the same as it is in Xcode which you did.
But App Store ID ("iPhone App Store ID that we can link to on Facebook") you set them when you already submitted you app and it's accepted. Therefore, for developing purpose you should set iPhone and iPad(if any) to 0 which I did and it's working fine on both Simulator and iPhone iOS 6.0.
It wasn't because of that 0, maybe you fixed something else?
Answered my own question: go to your Facebook app page and make sure that a "0" value hasn't been inserted automatically for your App Store ID. I had already set my bundle ID to the correct value (which you also have to do), but overnight, Facebook automatically set the App Store ID value to 0. Everything worked as soon as I removed that value.
I have implemented FBConnect SSO in my iphone application according to this tutorial. I have tested it on two phones so far, one of which lets me use the function just fine, whereas the other phone simply opens up the Facebook app and closes it right away. I am able to establish a valid session, yet the dialog seems to just close on me on one of the ones.
What could be the problem? Any help is much appreciated.
I think that your problem is that you dont have the proper configuration, either in the client side (your app) or in the server side (the FB app configuration). Please, check both things as follows:
Client app:
Make sure that you have introduced the correct FBAppId into your Info.plist as a URL handler. Facebook will try to open the app by using this handler, and if it doesn't work, your app will not be opened.
(replace the XXXXXXXXXX with your FB appID)
Check whether your app (in the appDelegate) handles the custom URL added above:
- (BOOL)handleOpenURL:(NSURL*)url
{
NSString* scheme = [url scheme];
NSString* prefix = [NSString stringWithFormat:#"fb%#", facebookAppId];
if ([scheme hasPrefix:prefix]) {
return [fb handleOpenURL:url];
}
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [self handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [self handleOpenURL:url];
}
Server side
Check that you have correctly configured your bundleId in the FB config page. You can check this in https://developers.facebook.com/apps, selecting you app, and then in the edition panel:
If you have both things correctly configured it should work in any case (with the FBapp installed or Safari based).
I have seen this with the 3.0 SDK. The reason it occurs is because of the way facebook caches access tokens. Access tokens are cached both in your app, and in the facebook app on the device (at least conceptually).
If it's the first time you started your app on the device, facebook won't have a valid access token cached in your app. However, it may still have a valid access token in the facebook app for your app. If it finds one on the facebook side, then it doesn't have to ask the user again, so the dialog appears, then disappears, and it sends back the access token. The access token is then cached in your app.
If you restart your app (without deleting it), you won't see the login dialog at all since the access token is now cached in your app. If you delete your app on the device and login again, you'll see the same behavior, as long as facebook can find a cached token on it's side.
I have found a solution to this problem. Here is some sample code:
if (![FBSession activeSession].isOpen) {
FBSession *session = [[FBSession alloc] initWithAppID:nil permissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone urlSchemeSuffix:nil tokenCacheStrategy:nil];
[FBSession setActiveSession:session];
[session openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
// NOTE openActiveSessionWithPermissions causes the facebook app to hang with a blank dialog if my app is installed, authed, and then reinstalled. openWithBehavior
// does not. I think it has something to do with the FBSession activeSession.
// [FBSession openActiveSessionWithPermissions:self.permissions allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
switch (status) {
case FBSessionStateOpen:
[self getFacebookUser];
break;
case FBSessionStateClosed:
[self fbSessionClosed];
break;
case FBSessionStateCreated:
[self fbSessionCreated];
break;
case FBSessionStateCreatedOpening:
[self fbSessionOpening];
break;
case FBSessionStateClosedLoginFailed:
[self fbSessionClosedLoginFailed];
break;
case FBSessionStateOpenTokenExtended:
[self fbSessionOpenTokenExtended];
break;
case FBSessionStateCreatedTokenLoaded:
[self fbSessionCreatedTokenLoaded];
break;
}
}];
}
}
openActiveSessionWithPermissions causes problems, but openWithBehavior does not. openActiveSession makes the same openWithBehavior call, but I think the timing of setting the active session is different, and hence does not work. If I set the active session before calling openWithBehavior, everything seems to work fine. As far as your app and the end user are concerned, everything is identical.
You need to insert suitable logging throughout your code, post the code, and post what logs are being made in the working and the failure cases.
To make a log (see here for more advanced techniques):
NSLog(#"My log text");
At a minimum you need to add logs in all the callbacks from the Facebook API (even the ones you aren't using), and in your handleOpenURL and openUrl methods in the application delegate.
Your logs will appear in the Console in the Xcode Organizer when you connect the device you are testing with - that should show you what is happening.
FYI, the Facebook SDK code will first attempt to use the native app if it is installed, otherwise it will launch the Safari browser to ask for authorization through the web version of Facebook.
You should double check your Facebook URL scheme configuration, as described in the answer by Angel GarcĂa Olloqui.
My application is approved and ready to sale in appstore today. I downloaded it from appstore immediately but when I open my application there is no ads in my application. I dont understand anything.
In my code if user buy inapp item I set the value of userdefault to TRUE.
So when application starts Im checking this userdefaults. If it is TRUE I dont show any ads , if not I call ads api.
this is part of inapp purchasing area :
if ([productId isEqualToString:#"dontshowads"])
{
//user bought inapp item. so I must remove advertorials.
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:#"aldimi_lite_reklamikaldirma_099"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
and this is viewwillappear area :
BOOL appin_reklamkaldirmaalindimi = [[NSUserDefaults standardUserDefaults] boolForKey:#"aldimi_lite_reklamikaldirma_099"];
NSLog(#"appin_reklamkaldirmaalindimi :%d",appin_reklamkaldirmaalindimi);
if (!appin_reklamkaldirmaalindimi)
{
NSLog(#"showing ads");
}
else {
NSLog(#"no ads. user bought inapp item");
}
When I run my application in simulator everything is fine. (I deleted it first in simulator and re build it)
Console gives this logs:
appin_reklamkaldirmaalindimi : 0
showing ads
When I run my application in my real phone everything is fine also. (I deleted it first in my phone and re build it)
Console gives this logs:
appin_reklamkaldirmaalindimi : 0
showing ads
But when I run my application which is downloaded from appstore everything is different.
Console gives this logs:
appin_reklamkaldirmaalindimi : 0
no ads. user bought inapp item
I tried to download and check the situation in my friends phone . Everything is the same. So it is not about my phone.
how can it possible ? I thought one hour and I cant find any explanation to this situation ...
The only explanation for such a weird phenomenon is that the code which you submitted to the App Store is in some way corrupted or different than the code which you tested by building off your computer. The only way to fix this problem would be to resubmit your application to the App Store.
The only other possibility I can think of is that your app has some VERY poor and incorrect memory-access tendencies, such that part of your executable code or stack somehow gets over-written before running your ad logic.
When in airplane mode or any other state where network access is not available, will a call to NSFileManager's URLForUbiquityContainerIdentifier: return nil?
A follow up question to this is: if this call to URLForUbiquityContainerIdentifier: DOES not return nil but rather returns a valid URL when network access is not available is this a way to access cloud based documents offline?
The apple docs state that this will return nil if iCloud is not configured or not enabled. It does not mention what will happen if network access is not available.
I would test this myself but from what I understand I would have to test this on an actual device and testing on a device is not possible for me at this time. Thank you!
The UbiquityContainer is a local storage container that contains the documents you requested from iCloud. This container is available when when the network is not. By using the following example
NSURL *ubiq = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
if (ubiq) {
NSLog(#"iCloud access at %#", ubiq);
// TODO: Load document...
} else {
NSLog(#"No iCloud access");
}
You will be able to access the files and ubiquity container when the phone is even in airplane mode. When the network connections restore the icloud daemon will automatically sync the files even in the background.
Here is a great article on iCloud setup.
http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1