In one of my iOS app, I am seeing multiple crashes while accessing the Keychain (in both cases i.e. setting an item & getting an item) and the error code is 25308.
Few details:
1) I am using a 3rd party keychain wrapper https://github.com/kishikawakatsumi/KeychainAccess
2) The accessibility option is set to 'whenUnlockedThisDeviceOnly'
3) This is not happening to all users. I am unable to reproduce it by any chance.
4) I am accessing keychain at few places in AppDelegate. Few crashes are reported on app launch and few are reported on Firebase token refresh notification observer method.
5) In didFinishLaunch, I am trying to access the value for a keychain item where as in Firebase token refresh, I am trying to set the new token value to the keychain.
On my findings I understood that this error code 25308 will be returned when user tries to access the keychain when a device is in locked state. But my Fabric (crash reporting tool) shows that the 'App is in Focus' in all these crashes.
So this got me confused with multiple questions like:
1) What else cases can throw this error 25308 other than device unlocked state?
2) Does firebase token refresh notification causes this background launching of app ? If so, how can I reproduce this. (One supporting thing here is I know that app was not uninstalled)
Update on 01/03:
It seems like the root cause for this is 'App is being launched when Firebase generates a new token and this launch is happening when device is in locked state, hence keychain access is throwing such error 25308.' So is anyone aware how a new firebase token launches the app which is already in terminated state??
Appreciate your responses on this. Thanks..
Related
I am running into a strange problem where the user was able to log in previously and now getting error 13 - Temporary password has expired and must be reset by an administrator. However, switching to a different device using the app login succeeds. Any ideas what needs to be done to clear cache or keys or anything else that is needed?
The documentation for didInvalidatePushTokenForType says its optional to implement and also says this
This method is invoked if a previously provided push token is no
longer valid for use. No action is necessary to request registration.
This feedback can be used to update an app's server to no longer send
push notifications of the specified type to this device.
Why on earth therefore would somebody not want to implement this? If the token is no longer valid then a server will never be able to send Voip pushes to that device again, so doesn't the app on the handset want to know as soon as possible if its invalided so it can send a new token to the server?
I've been trying to search for info and use of didInvalidatePushTokenForType() but it seems everybody just copy and pastes this method into their source code because everybody else has copy and pasted it. But nobody seems to ever do anything with it.
But seems to like it should be a vitally important method to make use of, so why does nobody apparently?
When would the token become invalid?
Thanks for the asking great question.
1) When would the token become invalid?
If we are update app from the App Store then APNS token doesn't change.
reinstalling the OS or Update OS or Reset iOS device then APNS token does change(Upgrade or downgrade OS).
Device token Invalidated or expired after 2 Years.
iOS9 and later device token changes if I reinstall an app.(As per my experience and Knowledge).
Download app from App Store then run your code using X-Code in this case device token will change.
2) Important of didInvalidatePushTokenForType() or Why? didInvalidatePushTokenForType() is optional
Let's clarify about didInvalidatePushTokenForType() method.
Once token got changed then called didInvalidatePushTokenForType() and didUpdatePushCredentials() method, So all code is placed in didUpdatePushCredentials() instead of didInvalidatePushTokenForType().
That's why Developer doesn't give important to didUpdatePushCredentials() method.
Find Reference from Here
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 am developing an App and testing on my physical iPhone.
At some point, the app checks if it is authorized to view the contacts (address book) of the phone using ABAddressBookGetAuthorizationStatus().
That call returns a status which can either be .Denied,.Authorized,.Restricted, .NotDetermined.
The last one is returned if you run the app for the first time, and have never approved or denied the app from accessing the device's address book.
Once you answer that authorization question, that answer is stored somewhere, and in the future, you will either get a .Authorized or .Denied status. Never again a .NotDetermined.
I tried deleting the app, and installing again. I tried changing the compile settings and changed the target build iOS. I did a Clean build, but I failed to get that status again.
I know I can copy the Xcode project and name the app something different to trick the iPhone into thinking this is a new app. But what is a straight forward way to let the app receive a .NotDetermined status again?
Go into the General settings and Reset Location and Privacy. (This will have other side effects, but there's nothing you can do about that.)
I'm creating a cloudkit app, and have been trying multiple ways to get the NSUbiquityIdentityDidChangeNotification, but I never am able to get this notification.
I've tried both of these code versions under the delegate didFinish and the viewDidLoad methods. And I tried calling it from another notification - UIApplicationDidBecomeActiveNotification. I also put import Foundation at top of files.
Here's the basic code I've tried:
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "handleIdentityChanged:",
name: NSUbiquityIdentityDidChangeNotification,
object: nil)
// And this one I tried too from another post here on SO:
var localeChangeObserver = NSNotificationCenter.defaultCenter().addObserverForName(NSUbiquityIdentityDidChangeNotification, object: nil, queue: NSOperationQueue.mainQueue()) { _ in
println("The user’s iCloud login changed: should refresh all user data.")
}
Does anyone know how to get this notification to work for only a cloudkit app in swift? I really just want to detect the iCloud status change and then initiate fetching the userID if there's been a change.
Not that I need to access the ubiquityIdentityToken, but I was wondering why not store the token and every-time the app starts compare the current token with the one in local storage to see if it's a different account or nil? Therefore, why is getting the notification necessary?
Also, the code for getting the token only seems to work if I turn on "iCloud Documents", which I don't need. Does anyone know the implications of having that turned on for a social app that doesn't need it? And is there another way to get the token without enabling iCloud Documents?
This is the code I used to get token and placed in the delegate didFinish method, but only works if iCloud documents is turned on:
var token = NSFileManager.defaultManager().ubiquityIdentityToken
println("token is \(token!)")
On iOS, when I sign out of iCloud, my app is killed. So there seems not really to be a need to receive a NSUbiquityIdentityDidChangeNotification. Like you have said, it seems to be sufficient to compare the current token to the saved token.
On the Apple TV though, my app was not killed when I logged out of iCloud. Here I had noticed the notification was not fired, like you described. Since the app is not killed, a notification would be in order. (Did Apple forget to kill apps on Apple TV when iCloud account is changed?)
With Apple TV there is no iCloud documents container available (unless I explicitly share one from an iOS app). I found that on the dev center website, for the app identifier, iCloud was shown as "Configurable" and not "Enabled" if no document container was selected. I wonder if this has an effect on receiving notifications.
Both on the Apple TV and iOS, I can also confirm that the iCloud token is nil when not using documents (here: key-value-store only). Now that makes it difficult for Apple TV apps (because the app is not killed on iCloud account change, like on iOS) to detect account changes.
I have just noticed that my Apple TV app does received several NSUbiquitousKeyValueStoreDidChangeExternallyNotification when I log into another iCloud account, to reflect the changes. I guess this is as good as it gets. These notifications come with the NSUbiquitousKeyValueStoreChangeReasonKey key in userInfo, and a value of NSUbiquitousKeyValueStoreAccountChange indicates the account has changed.
Sorry for not being able to provide a direct solution, maybe it helped to share my experience.
To be notified in iOS when a user logs in or out of iCloud while using your app, use CKAccountChangedNotification instead of NSUbiquityIdentityChanged notification.
(Longer explanation: https://stackoverflow.com/a/38689094/54423.)