I have a weird behavior happening to me while using the watch connectivity.
I start the session from the AppDelegate's didFinishLaunchingWithOptions.
The user's goes through the login process, and when the user get's to the home screen if the user open's the Watch it seems that something goes wrong with the session.
At this point I get this log:
[WC] -[WCSession onqueue_handleDictionaryMessageRequest:withPairingID:]_block_invoke delegate MCEWatchSessionDelegate does not implement delegate method
[WC] -[WCSession _onqueue_sendResponseError:identifier:dictionaryMessage:] identifier: [identifier] with WCErrorCodeDeliveryFailed
And at this moment if I print the error on the watch if get:
Error Domain=WCErrorDomain Code=7014 "Payload could not be delivered." UserInfo={NSLocalizedDescription=Payload could not be delivered.}
and there is nothing in the login process using the session or anything related to the WatchConnectivity.
If the user opens the watch app on the login screen, everything works as expected.
If I close and open the app again (session get's activated again) it runs normally and the issue is gone.
If I activate the session again from the iPhone app after the watch has tried and failed to send the message, it goes back to normal.
If I dispatch a queue with a delay, activating the session again on the Iphone app to after the home screen is shown, it also work's normally.
The problem seems to happen only on the first time the user enters the application after the installation, manually log's in and get's to the home screen.
Related
I've just implemented the ATT request in my applications. It appears at the app first opening but I would like to show it again if the user wants to change his preferences from the app settings (internal).
I tried to call the requestTrackingAuthorization method again but it enters immediately to the completion handler. Is there a way to reset the status?
Upon launch on an iOS10 device, I get the following output:
[MC] Reading from public effective user settings.
[SDKPlayback] MPMusicPlayerController] MPMusicPlayerController: Server is not running, deferring check-in
[SDKLibrary] Not authorized, skipping filter predicate application
The app plays music from the user's library and therefore must ask permission, so I have updated info.plist with the required key strings for NSAppleMusicUsageDescription but the app crashes as soon as the predicate is called. When the app is stopped and the launch screen disappears, the permission window is finally displayed. If I tap allow, subsequent launches will work just fine.
My question is: Does the "server not running" error have anything to do with the permissions window not being shown? If so, how do I start it?
So, the way an MPMusicPlayerController works is:
You have to have the key in the Info.plist, as you already know.
In your code, check authorization with MPMediaLibrary.authorizationStatus.
If you don't have authorization, you request authorization using MPMediaLibrary.requestAuthorization. You cannot proceed until you have authorization. Be careful because the call is asynchronous and the completion is called on a background thread.
Now you make an MPMediaItemCollection and call setQueue(with:) and then play.
I have a Cordova app that records user's trips. It works fine in the background, and I'd like to get it automatically restarted if it's killed for some reason (user swipes it away, phone restarts, etc.).
I'm monitoring a region, and the app partially restarts when the user enters/exits from that. 'Partially' here means the app only runs in the background - Cordova loads my app's plugins, but it never loads the WebView.
For this partial restart, I'm listening for UIApplicationDidFinishLaunchingNotification with UIApplicationLaunchOptionsLocationKey from my plugin's pluginInitialize method and starting location services right away to stay running.
Why doesn't the WebView load? Is there something I need to do to trigger the next stage of initialization when started by iOS?
EDIT 2016/3/7
I did some research and debugging. Apparently, iOS starts my app in the background; here's what I get when auto-started this way vs. a manual start, from the logging line:
NSLog(#"Launched in: bg:%d active:%d inactive:%d", state == UIApplicationStateBackground, state == UIApplicationStateActive, state == UIApplicationStateInactive);
Launched in: bg:1 active:0 inactive:0
Launched in: bg:0 active:0 inactive:1
I verified this code was being reached in both cases (from cordova-ios' v.3.9.2 (Cordova v.5.4.1) CDVViewController:
NSURLRequest* appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
[self.webView loadRequest:appReq];
I see this load finish in the manual case, but not the auto-start case, with the log line:
Finished load of: file:///var/mobile/Containers/Bundle/Application/[device id]/[app name].app/www/index.html
Why would this load fail when auto-started?
I ended up using an Apple support ticket; their answer is basically "you can't load a web view when started that way":
If I understand correctly, you are expecting your app to visibly launch to the foreground when you get a location update.
that is not how it works at all. Your app will be launched into the background. If you see the UIApplicationLaunchOptionsLocationKey, only your app delegate and the location manager’s delegate class will be initialized. No views will be initialized whatsoever.
Once an app is launched in the background, it is expected to process the data for a few seconds silently and then yield back to the system. It is not possible to load a web view, or any kind of UI at this stage.
The only user interaction that would be possible is to schedule a local notification with a message to the user to launch the app. If the user taps the notification, your app will be fully launched.
Only then you can load your web view.
I have a problem with launching media from iOS app. When I call mediaControlChannel loadMedia:, nothing happens on receiver app - no loading bar appears, but neither of GCKMediaControlChannelDelegate methods are being called. After waiting some time, when I disconnect from the device, only then delegate receives didFailToLoadMediaWithError with error 92: unexpected disconnect.
I thought that the media or some of the parameters are incorrect, so I used them in Google's example iOS app, but it all works fine there.
Before trying to load media I check if I'm connected to device and to the application, mediaControlChannel is added to deviceManager. I also call requestStatus on mediaControlChannel to make sure I don't get kGCKInvalidRequestID and everything's fine. Only then I try to load media, but as I said - it just doesn't work, no error, no feedback from receiver app. I'm out of ideas.
As the title says, my project will never bring up the FB login screen until I have called
[facebook logout];
This makes sense when I've already logged in, but it happens on startup as well (i.e. the user is not yet logged in).
Hmmm...I've just tried resetting contents and settings in the simulator, and that seems to have fixed the problem. For my own peace of mind, why when I close the simulator and rerun the project does it not revert to either a state where the app is 'new' and hasn't been run before, or to a resume state - whereby the logged in user info would be available immediately?
On my device I have just tested this:
Fresh install
Open app, login via FB Connect
Close app, remove from running in background apps
Reopen app
Try to login, no response until I first click logout
So is it somehow retaining the fact that it has logged in before? If so, is there a "loggedInAlready" variable or something similar that I can check against?
Added this to didFinishLaunchingWithOptions
if([facebook isSessionValid])//if already able to log in
{
[self loginToFacebook];//attempt to login automatically on startup
}
Seems to have solved the problem. I guess that because I had:
if([facebook isSessionValid]){
[facebook login];
}
in the login button press, that when it resumed it was still in a valid session and so the button press wouldn't do anything until the logout button ended the session.
Now it automatically checks if the session is valid on startup, and if so it logs straight in for me.
:-) All's well that ends well.