can't reference firebase database in applicationWillTerminate - ios

I am trying to update my firebase database before the app being forced to close to no avail.
Settings:
Xcode Version: 8.2.1
ios simulator
Info.plist > Application does not run in background: Bool YES
Simulate:
Launch application
Close application via Hardware > Home on simulator
Code: AppDelegate.swift
this updates
func applicationDidEnterBackground(_ application: UIApplication) {
let user = FIRAuth.auth()!.currentUser!
FIRDatabase.database().reference().child("status").child(user.uid).setValue("foobar")
}
this does not update (print is functioning)
func applicationWillTerminate(_ application: UIApplication) {
print("applicationWillTerminate")
let user = FIRAuth.auth()!.currentUser!
FIRDatabase.database().reference().child("status").child(user.uid).setValue("foobar")
}
Here is screenshot of my db structure
sample
Since I have 5 seconds to execute an asynchronous task, I feel like it should work
Your implementation of this method has approximately five seconds to
perform any tasks and return. If the method does not return before
time expires, the system may kill the process altogether.
https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate
any clues?

Related

Why async / long running operations in BackgroundTasks don't work?

Trying to use BackgroundTasks for iOS 13+. Long running operations don't seem to work:
// in AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
BGTaskScheduler.shared.register(forTaskWithIdentifier: "foo.bar.name", using: nil) { task in
print("start!")
task.expirationHandler = {
// Not executed
print("expired!")
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
// Not executed
print("finish!")
task.setTaskCompleted(success: true)
}
}
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
BGTaskScheduler.shared.cancelAllTaskRequests()
let request = BGProcessingTaskRequest(identifier: "foo.bar.name")
request.earliestBeginDate = nil // or Date(timeIntervalSinceNow: 0) or Date(timeIntervalSinceNow: 5)...
do {
try BGTaskScheduler.shared.submit(request)
} catch let e {
print("Couldn't submit task: \(e)")
}
}
I also tried using a queue with Operation (for which I modeled my flow synchronously). This also didn't work. As soon as there's something that takes a while to complete, it gets stuck.
It doesn't log anything else to the console, no errors, no expired task message. It shows the last message before the long running operation and that's it. I confirmed that it doesn't move forward by storing a preference and examining it when restarting. It's not stored.
I added "foo.bar.name" to the info.plist (in "Permitted background task scheduler identifiers") and enabled capabilities both for background fetch and background processing. I'm testing on an iPhone with iOS 13.3.1 and using Xcode 11.4.1.
Additional notes:
I've been starting the tasks immediately as described here: https://developer.apple.com/documentation/backgroundtasks/starting_and_terminating_tasks_during_development
I also tested with Apple's demo project. It shows the same problem: The database cleaning operation doesn't complete (I added a log at the beginning of cleanDatabaseOperation.completionBlock and it never shows).
A couple of observations:
You should check the result code of register. And you should make sure you didn’t see your “Couldn't submit task” log statement.
Per that discussion in that link you shared, did you set your breakpoint immediately after the submit call? This accomplishes two things:
First, it makes sure you hit that line (as opposed, for example, to the SceneDelegate methods).
Second, if you just pause the app manually, some random amount of time after the app has gone into background, that’s too late. It has to be in that breakpoint immediately after you call submit. Then do e command. Then resume execution.
Anyway, when I do that, running your code, the BGProcessingTaskRequest ran fine. I’m running iOS 13.4.1 (and like you, Xcode 11.4.1).

How to track the time a user listens an specific podcast

I have an iOS app that is about podcasts and I want to track how long a user listens every podcast. I have tried the basic - when a user plays I save the timestamp and when stops it sends an event with the timestamp difference but it obviously doens't work because there's many edge cases.
I have issues to know when a user has the app in background and stops listening at some point through the the system controls. Also when the user or the system kills the app without tapping on "pause" or "stop". I think these 2 cases are my main non-tracked cases so far.
Any idea how can I build a working solution? I don't want/can't pay an external service - I am merely relying on Firebase.
Thanks!
You can override applicationWillTerminate method in your app, and save a current user progress to UserDefaults.
As docs say, you have few seconds to do it:
This method lets your app know that it is about to be terminated and
purged from memory entirely. You should use this method to perform any
final clean-up tasks for your app, such as freeing shared resources,
saving user data, and invalidating timers. Your implementation of this
method has approximately five seconds to perform any tasks and return.
Your code can look like this:
var player: AVPlayer!
func applicationWillTerminate(_ application: UIApplication) {
UserDefaults.standard.setValue(player.currentTime().seconds, forKey: "curPlayerTime")
}
Then, on application launch, you can restore it:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let lastPlayerTime = UserDefaults.standard.value(forKey: "curPlayerTime") as? Double {
// update your player
}
return true
}

strange error/SIGABRT thread 1

A couple of strange errors appeared in my code after I made a duplicate of the folder, I deleted the duplicate but I have some errors remaining..
Thread 1 SIGABRT error when running, build completes but doesn't load.
error is on the line with class AppDelegate
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
The other error lies in the image.
thanks for the help.
When you delete a file from Xcode, you should choose "Move to Trash".You can just add it to Xcode again, and delete it use "Move to Trash".
Go to the "Breakpoint navigator", click the "+" button at bottom, the choose the "Exception Breakpoint...". When the crash happen again, Xcode should stop at your exception code.
there is an Unreferred Outlet in your ViewController , Right click on your start ViewController and make sure there is no exclamation point in front of Outlets
Go to Build Phases -> Compile Sources, and see whether the app has two "ViewController.swift" files. If yes delete the one which you don't want.
Hope this helps you!

Xcode showing multiple warnings in AppDelegate after updating to version 8?

I had updated my Xcode 7.3 to Xcode 8.
It is showing multiple warnings in AppDelegate. The warning is as follows.
Extraneous '_' in parameter: 'application' has no keyword argument name
My AppDelagate.swift file is this:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
when I followed the Xcode suggestion to remove _ in the functions that shows warning.
I got rid of the above warning. But now I get a new warning for
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
The warning is:
Non-#objc method 'application(_:didFinishLaunchingWithOptions:)' cannot satisfy optional requirement of #objc protocol 'UIApplicationDelegate'
I followed the solutions online. But had no luck in getting rid of this warning.
Any help would be appreciated.
Thanks.
Your code is correct for Swift 3. But the environment you are in clearly thinks it is supposed to be Swift 2, and that is the reason for the error messages.
It sounds as if you have accidentally opened the file in Xcode 7. That would explain it. Your code is now Swift 3. Xcode 7 is Swift 2; it does not know about Swift 3 and doesn't understand your code.
Now that you have converted to Swift 3, you can never use Xcode 7 with this project ever again.
Or maybe this is Xcode 8 but the legacy build setting is still on, so it thinks this is supposed to be Swift 2. But it isn't. It is Swift 3.

SourceKitService Crashed in Xcode 6.1.1

I started having an issue with Xcode 6.0.1 where the error "SourceKitService Crashed Crashlog generated in ~/Library/Logs/DiagnosticReports" started popping up and all syntax highlighting was gone in Swift. Then Apple released a new update Xcode 6.1.1 where mentioned this issue was resolved. So I updated my Xcode to 6.1.1 but this problem still exists. I my case the issue is just staying there and never disappearing.
I tried few solutions found in StackOverflow like deleting the content of: DerivedData/ModuleCache, cleaning up the project etc but the issue still exists.
I am not able to make a build and whenever I try to get these 2 errors.
/Users/MY_PROJECT/AppDelegate.swift:11:1: 'UIApplicationMain' class must conform to the 'UIApplicationDelegate'
protocol at UIApplicationMain in my AppDelegate.h file and this Command failed due to signal: Segmentation fault: 11
Here is the code of my AppDelegate.swift
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
return true
}
func applicationWillResignActive(application: UIApplication!) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication!) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication!) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication!) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication!) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
I'am not sure about the cause of this error, i was getting this sourcekit crash for various reasons. For you if you look into UIApplicationDelegate methods, they are slightly changed in the signature. For eg UIApplication parameter is not optional now.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
So if you compare your delegate methods with new UIApplicationDelegate methods(if you command+click you can check the method signature)and make changes you may get rid off this error. Give a try.

Resources