iOS Notification when App is in Background

2020-07-30 01:24发布

i want to know if it is possible to launch a background process in iOS. In my background process every 30 minutes there should a function get called, in order to check in my database if there are new messages, etc in order to send a notification. I don't want to implement push notifications. I don't know where to implement this feature, and if there are override functions e.g. in the AppDelegate.

Thanks for your help, hannes

4条回答
爷、活的狠高调
2楼-- · 2020-07-30 01:55

For background

In your viewDidLoad() method

 let notificationCenter = NotificationCenter.default
 notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)

Add this method in your ViewController

 @objc func appMovedToBackground() {
   print("App moved to background!")
 }

For Forground

  override func viewDidLoad() {
    super.viewDidLoad()


    let notificationCenter = NotificationCenter.default
    notificationCenter.addObserver(self, selector: #selector(appMovedToForground), name: UIApplication.willEnterForegroundNotification, object: nil)

 }

@objc func appMovedToForground() {
   print("App moved to forground!")
}
查看更多
走好不送
3楼-- · 2020-07-30 02:01

What you want is called "Background Fetch" and is available starting from iOS 7:

https://www.objc.io/issues/5-ios7/multitasking/

查看更多
我欲成王,谁敢阻挡
4楼-- · 2020-07-30 02:01

I would recommend that you take a look at Apple's documentation on Background Execution. It states all the possible ways to run code in the background. Each method comes with it's limitations, advantages and disadvantages and also Apple mentions:

In iOS, only specific app types are allowed to run in the background

If your iOS application does not communicate over Bluetooth (BTLE or with MFi certified devices) with some device (you could configure that Bluetooth device to send some event to the iOS device every 30 minutes and execute your code when that happens), then the most reliable way to run some code every 30 minutes is by using silent push notifications.
Silent push notifications can be configured so that they're not shown to the user, but allows your code to run. The limitations with push notifications are that the user needs an active internet connection to receive them and the user needs to give your app permission to use push notifications (you can request this at app's first run).
I noticed that your questions mentions I don't want to use push notifications, but unfortunately you don't really have a choice here.

查看更多
啃猪蹄的小仙女
5楼-- · 2020-07-30 02:08

Yes it is possible to launch a background process in iOS. It is also possible to launch this process every 30 minutes. You need to setup two things! You need to send every 30 minutes a silent Push with your server.(e.g. with a Cloud Code job in Parse(Warning! Since Parse will be shutdowned in January 2017, it is not clever working on this platform)

This silent push initiate an NSURLBackgroundSession which pulls the desired data from your server and process it.

Your need to activate this in the project settings

1.) Add this in AppDelgate for receiving pushes

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
    application.registerForRemoteNotifications()
}

When you get a push from a server or something else, following delegate method will be called: (so add this too in your appDelegate)

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
     {
        NSLog("Silent Push recevied")
        let vc = ViewController()
        vc.pullData() // call your pullData method...
     }

The method which is called now needs to pull the data from your database. In this case you use a NSURLSession to download whatever you need.

2.) Go to the ViewController where the data get processed and add: the NSURLSessionDownloadDelegate delegate with the required delegate methods

class vc : ViewController, NSURLSessionDownloadDelegate{
func viewDidLoad()
{
super.viewDidLoad()
}

func pullData()
{
let url = NSURL(string: "http://example.com")!
let urlRequest = NSURLRequest(URL: url, cachePolicy: .UseProtocolCachePolicy, timeoutInterval: 5)
let backgroundSessionConfiguration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("backgroundSessionIDX")
backgroundSession = NSURLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
let task = backgroundSession.downloadTaskWithRequest(urlRequest)
            task.resume()
}
}

When the downloadTask is successfully completed

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL)
{
}

will be called and you can process the data

let path = location.path
let data = NSFileManager.defaultManager().contentsAtPath(path!)

You can alternatively do this with a NSURLSessionDataTask

查看更多
登录 后发表回答