Posts

Post marked as solved
9 Replies
If I were in your shoes I’d: Set up a test device running iOS 14. Reset the alert state (FAQ-13). Run and exercise its functionality to see if you can trigger the alert. OK, I've done that and discovered that both my apps, once installed after updating to iOS 14, trigger the alert. So, does accessing data on the web - in a URLSession or by using SafariServices - trigger the alert? The presentation implies that it does not but your (very useful) list leads me to wonder. The only other thing I can think of is that both my apps determine the user's location. It seems like this should be handled fully by the location privacy setting?
Post marked as solved
9 Replies
Update: I've since installed iOS 14.0.1 onto my iPhone 7 Plus and it throws the same alert that is causing my app to be rejected in Review. And my app is then added to the list, in Settings, of apps that have asked for access to the Local Network. I still have no clue why.
Post marked as solved
9 Replies
I just discovered that my app had "Application supports iTunes file sharing" set to "YES". No idea how that happened. I've turned it off. Could that do it? I can't reproduce the problem except by submitting another build for review. [update] Another app of mine has the same setting turned on and there is no alert problem with that app. I gather it's a default setting. I've also discovered that my troubled app contained some c code with print statements. That particular code never executes (and I've deleted it). Could a print command that never runs cause the app to go look for a printer?
Post not yet marked as solved
3 Replies
How can I diagnose this? Unexpected demotion to the background continues to plague me. It happens only rarely and may only affect some users. My app is the active one, but suddenly is sent to the background. I've tried to use logging to sort it out but I see no evidence of low power, no memory warning, nothing except the .applicationWillResignActive event. In the most recent event, background operation commenced and app refreshes continued normally. But I need the app to stay active when that's what the user expects!
Post not yet marked as solved
4 Replies
I went through this several years ago and came to the dead end that HomeKit activity is only available to an app that is active in the foreground. I had to develop some fairly elaborate ways to work around this. I submitted feedback at the time but the bottom line was the security edict that background entitlement was not possible. Today I received a cryptic Feedback from Apple on that old request: "After reviewing your feedback, we have some additional information for you: The HomeKit entitlement is public now. Please close your feedback if this is no longer an issue for you. Thanks!" I haven't been able to figure out yet what this means!
Post not yet marked as solved
3 Replies
My disappearing app problem still happens with the timer tolerance set to 180, my timer code below.When my app enters "NightMode", I disable the Idle timer to keep the app active and in the foreground all night, and I turn on the proximity monitor to allow the screen to go black when the phone is placed face down. UIApplication.shared.isIdleTimerDisabled = true UIDevice.current.isProximityMonitoringEnabled = trueA user's log shows that the .isIdleTimerDisabled = true was correct at 1:36AM and again at 1:46AM. The log then goes blank, meaning the app was "dead". My app is heavily logged for debugging and won't do hardly anything without making a log entry. After 1:46 there was nothing about any of these events, which should all generate log entries:applicationWillResignActive applicationDidEnterBackground applicationWillTerminateThe app came back to life and logging in the background at 4:11AM this morning. It reported that the .isIdleTimerDisabled = false at that time. How did it get reset? What the heck happened to my app after 1:46AM?Starting my timer for NightMode: weak var timer: Timer? func startTimer() { timer?.invalidate() // just in case you had existing `Timer`, `invalidate` it before we lose our reference to it if #available(iOS 10.0, *) { timer = Timer.scheduledTimer(withTimeInterval: 600.0, repeats: true) { [weak self] _ in self?.timer?.tolerance = 180 // Upped from 80 on 5/27/20 let dateFormatter = DateFormatter() // format the date for output dateFormatter.dateStyle = DateFormatter.Style.medium dateFormatter.timeStyle = DateFormatter.Style.long let convertedDate = dateFormatter.string(from: Date()) self?.logSB.warning("The timer triggered at \(convertedDate)") } } else { // Fallback on earlier versions } }
Post not yet marked as solved
12 Replies
"This is now way beyond me."I know how that feels!"... the question is not 'how to force a complete reinstall' but rather 'why is the system blacklisting me'."Agreed, I've managed to do a clean re-install but the root problem remains. I submitted a ticket on that topic."I think you need to respond sooner than 20 seconds with a completion handler and I'm not sure you always want to indicate .newData if there was no new data."My understanding is that I have 30 seconds. Picking 20 is a bit of a kludge, a dropping of the guillotine blade. I would prefer to send a completion handler back when everything else is actually done (which may be much sooner). Or wrap up gracefully if the other stuff cannot complete in 30 seconds. But that stuff confuses me and I never worked through it all.Always reporting "newData" is the recommended trick to keep background fetch requests coming in as frequently as possible. It's not really cheating, since it will indeed be new data as long as it completes.
Post not yet marked as solved
12 Replies
Just to elaborate a bit more about how my fetches start and wrap up. I see now that I may have not properly set it up in iOS13. Not sure. See what you think. Maybe I need to invalidate any URL session still running?It works fine when everything gets done quickly but may not be graceful if/when the fetch does not complete in time. Note that one affected user I'm in contact with is on iOS 12 and another is on iOS 13. The iOS 12 user did the nuclear reinstall and now has normal function, ie. frequent background sessions. iOS 12 versionIn my AppDelegate: func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { let dateFormatter = DateFormatter() // format the date for output dateFormatter.dateStyle = DateFormatter.Style.medium dateFormatter.timeStyle = DateFormatter.Style.long var convertedDate = dateFormatter.string(from: Date()) if #available(iOS 13.0, *) { self.logSB.info("iOS 13 Ignoring Background Fetch called at \(convertedDate)") completionHandler(.newData) } else { Central().fetch { // Goes and gets fresh data convertedDate = dateFormatter.string(from: Date()) self.logSB.info("Calling the Fetch completion handler at \(convertedDate)\n\n") completionHandler(.newData) } // End call of Central().Fetch } // End else } // Close funcIn my Central file: func fetch(_ completion: @escaping () -> Void) { let dateFormatter = DateFormatter() dateFormatter.dateStyle = DateFormatter.Style.medium dateFormatter.timeStyle = DateFormatter.Style.medium let convertedDate = dateFormatter.string(from: Date()) self.logSB.info("Running the CENTRAL fetch at \(convertedDate)") self.getWebFetchesBackground() // This launches the URL sessions let timer = Timer.scheduledTimer(withTimeInterval: 20.0, repeats: false) { (timer) in completion() // This sends a completion back to the AppDelegate after 20 seconds. } }iOS 13 versionIn my AppDelegate: @available(iOS 13.0, *) func handleAppRefresh(task: BGAppRefreshTask) { logSB.info("Handling the AppRefresh in iOS 13") scheduleAppRefresh() let queue = OperationQueue() queue.maxConcurrentOperationCount = 1 let appRefreshOperation = Central().fetch2 queue.addOperation(appRefreshOperation) let lastOperation = queue.operations.last lastOperation?.completionBlock = { task.setTaskCompleted(success: !(lastOperation?.isCancelled ?? false)) } task.expirationHandler = { // After all operations are cancelled, the completion block below is called to set the task to complete. queue.cancelAllOperations() } let dateFormatter = DateFormatter() dateFormatter.dateStyle = DateFormatter.Style.medium dateFormatter.timeStyle = DateFormatter.Style.long let convertedDate = dateFormatter.string(from: Date()) self.logSB.info("Completed the iOS 13 App Refresh at \(convertedDate)") }In my Central file: func fetch2() { let dateFormatter = DateFormatter() dateFormatter.dateStyle = DateFormatter.Style.medium dateFormatter.timeStyle = DateFormatter.Style.medium let convertedDate = dateFormatter.string(from: Date()) self.logSB.info("Running the NEW CENTRAL fetch at \(convertedDate)") self.getWebFetchesBackground() }
Post not yet marked as solved
12 Replies
"Also, have you checked UIBackgroundRefreshStatus to be sure it is still set?"I have recently incorprated logging the status that into didFinishLaunchingWithOptions in my AppDelegate. It appears to be "available" for the affected users, at least when the app starts.As for satisfying the system that my fetches wrap up properly, I guess I'm not sure. I get background fetches all day long just fine, so in general I feel the code is OK. Other users too. But if there is something about the affected users that is causing a problem with getting done in time (slow internet?), I suppose my app might be getting blacklisted. I need a way to check that and more importantly to reset it when a new build is installed
Post not yet marked as solved
12 Replies
" 1) regarding keychain: ... keychain entries do not get deleted when an app is deleted from the device. "So this is a potential source of my problem, if the system has placed something there that interferes with my app."All other files get deleted when the app is deleted from the device. I do not know if iCloud key-value file gets deleted, but I think not."Definitely not in the short run, and I think not ever. (The cloud file, I mean, nothing local.) This enables you to trash an app and reinstall it at a later date while retaining some of the old information." 3)> Turning off background app refresh before reinstalling the appI am not familiar with 'background app refresh' - what is that?"Check out your Settings>>General>>Background App Refresh to find a list of apps on your phone using this feature. It allows a small amount of resources for apps to operate in the background to fetch fresh web data, for instance." 4) ThIs this a race issue where the app reinstalls and starts faster than the app can download something in the background? " No, it's a matter of the system never allocating those meager background resources despite all the pieces being in place. Once the system cuts off an app, it seems impossible to get going again. It happens every 20 minutes or so when things are rolling.
Post not yet marked as solved
12 Replies
Logging out is not required. The user took that upon himself after it became clear that new builds of the app (delivered via TestFlight or the app store) did not solve the problem. Turning off background app refresh before reinstalling the app accomplishes the same thing - it blows away all old settings - and is far less disruptive. Of course it's still a pain for users and I'd love to find another way.The root problem is that users can find themselves never being allocated background time for the app to perform web fetches. There is seemingly nothing that can be done internally in the app to restore background fetches once that state is reached. I would love to learn otherwise.
Post not yet marked as solved
2 Replies
I'm still trying to diagnose why there is little or no allocation of background time for background fetches for a few troubled users. I uncovered a big clue today by taking a user thru a nuclear re-install: Trash the app, sign out of AppleID, reinstall, open the app, log back into AppleID. This lost all settings but restored normal function of background fetches.My app uses iCloud storage of key-value data to backup the users settings. This preserves settings thru a normal re-install and also allows the app to be portable to the user's iPad or AppleTV.Something toxic can also stored there, apparently. Are there any tools for resetting the iCloud data, or for examining it to determine where the toxic information lives? I'm not sure how to proceed.As an aside, one user does not put his phone on a charger overnight and experienced erratic behavior. I looked into checking the power situation:let dateFormatter = DateFormatter() .dateStyle = DateFormatter.Style.medium .timeStyle = DateFormatter.Style.long let convertedDate = dateFormatter.string(from: Date()) UIDevice.current.isBatteryMonitoringEnabled = true var batteryState: UIDevice.BatteryState { UIDevice.current.batteryState } switch batteryState { case .unknown: self?.logSB.debug("The batteryState is UNKNOWN at \(convertedDate)") case .unplugged: self?.logSB.debug("The batteryState is UNPLUGGED at \(convertedDate)") case .charging: self?.logSB.debug("The batteryState is CHARGING at \(convertedDate)") case .full: self?.logSB.debug("The batteryState is FULL at \(convertedDate)") default: self?.logSB.debug("The batteryState is unknown at \(convertedDate)") } var batteryLevel: Float { UIDevice.current.batteryLevel } self?.logSB.debug("The battery level is \(batteryLevel) at \(convertedDate)") let myState = UIApplication.shared.applicationState switch myState { case .background : self?.logSB.info("The app state was found to be Background at \(convertedDate)") case .inactive: self?.logSB.info("The app state was found to be Inactive at \(convertedDate)") case .active: self?.logSB.info("The app state was found to be Active at \(convertedDate)") default: self?.logSB.info("The app state was found to be Unknown at \(convertedDate)") }
Post not yet marked as solved
3 Replies
I was just reminded that I've fought this battle before:https://forums.developer.apple.com/thread/82830Maybe I'll trying upping the timer tolerance again.
Post not yet marked as solved
2 Replies
Alright I guess I'm shouting into an empty canyon, but I'm pretty sure my problem is that background fetches are never triggered for my affected users. The alerts work fine but they normally trigger at the end of a successful fetch, and there are none. They trigger fine for my iPhone and in Simulator, but users are never seeing a fetch. Alerts triggered by crossing a geofence border work fine. But no background fetch ever gets asked for.I'm going to doublecheck the authorization for fetches as below but I have no reason to suspect they are not enabled. In my App Delegate: switch UIApplication.shared.backgroundRefreshStatus { case .available: self.logSB.debug("backgroundRefreshStatus is AVAILABLE") case .denied: self.logSB.debug("backgroundRefreshStatus is DENIED") case .restricted: self.logSB.debug("backgroundRefreshStatus is RESTRICTED") default: self.logSB.debug("backgroundRefreshStatus is unknown") }
Post not yet marked as solved
2 Replies
Found another one! : switch UIApplication.shared.backgroundRefreshStatus { case .available: self.logSB.debug("backgroundRefreshStatus is AVAILABLE") case .denied: self.logSB.debug("backgroundRefreshStatus is DENIED") case .restricted: self.logSB.debug("backgroundRefreshStatus is RESTRICTED") default: self.logSB.debug("backgroundRefreshStatus is unknown") }