前面讲了如何让程序申请后台短时运行。但这个额外延长的时间毕竟有限。所以从iOS7起又引入两种在后台运行任务的方式:后台获取和后台通知。

1,后台获取介绍

Background Fetch)是为了那些需要定期更新的应用程序设计的,比如天气应用,新闻客户端,社交网络应用程序等。在启动后台获取之后,应用程序可以在后台被唤醒,在后台获取最新信息,以便在用户将应用程序转到前台时能够立即显示这些信息。


2,后台获取功能开启

Capabilities(功能)选项卡,启用Background Modes(后台模式)中的Background Fetch(后台获取)


swift 申请后台运行 10分钟 swift写后端_获取数据




3,后台获取时间间隔设置


setMinimumBackgroundFetchInterval()方法设置最短唤醒程序的时间间隔(秒)。但具体什么时候程序会被唤醒获取数据,就不可控了。这个由系统自己决定。

UIApplicationBackgroundFetchIntervalMinimum。

4,使用样例


程序挂起后,自动从后台获取北京时间,获取后使用本地通知提醒用户。


(注意:后台获取执行后要调用completionHandler,告诉系统获取数据是否成功)


  

swift 申请后台运行 10分钟 swift写后端_获取数据_02

  

swift 申请后台运行 10分钟 swift写后端_xcode_03

import UIKit
 
@UIApplicationMain
class AppDelegate : UIResponder , UIApplicationDelegate {
     
     var window: UIWindow ?
     
     func application(application: UIApplication ,
         didFinishLaunchingWithOptions launchOptions: [ NSObject : AnyObject ]?) -> Bool {
             //开启通知
             let settings = UIUserNotificationSettings (forTypes: [. Alert , . Badge , . Sound ],
                 categories: nil )
             application.registerUserNotificationSettings(settings)
             return true
     }
     
     func applicationWillResignActive(application: UIApplication ) {
     }
     
     func applicationDidEnterBackground(application: UIApplication ) {
         //虽然定义了后台获取的最短时间,但iOS会自行以它认定的最佳时间来唤醒程序,这个我们无法控制
         //UIApplicationBackgroundFetchIntervalMinimum 尽可能频繁的调用我们的Fetch方法
         application.setMinimumBackgroundFetchInterval( UIApplicationBackgroundFetchIntervalMinimum )
     }
     
     func applicationWillEnterForeground(application: UIApplication ) {
     }
     
     func applicationDidBecomeActive(application: UIApplication ) {
     }
     
     func applicationWillTerminate(application: UIApplication ) {
     }
     
     //后台获取数据
     func application(application: UIApplication ,
         performFetchWithCompletionHandler completionHandler: ( UIBackgroundFetchResult ) -> Void ) {
             //创建NSURL对象
             let url: NSURL ! = NSURL (string: "http://api.k780.com:88/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json" )
             //创建请求对象
             let request: NSURLRequest = NSURLRequest ( URL : url)
             
             let session = NSURLSession .sharedSession()
             
             let dataTask = session.dataTaskWithRequest(request,
                 completionHandler: {(data, response, error) -> Void in
                     if error != nil {
                         print (error?.code)
                         print (error?.description)
                         
                         //让OS知道获取数据失败
                         completionHandler( UIBackgroundFetchResult . Failed )
                     } else {
                         let str = NSString (data: data!, encoding: NSUTF8StringEncoding )
                         print (str)
                         //清除所有本地推送
                         //UIApplication.sharedApplication().cancelAllLocalNotifications()
                         //创建UILocalNotification来进行本地消息通知
                         let localNotification = UILocalNotification ()
                         //推送时间(立刻推送)
                         localNotification.fireDate = NSDate (timeIntervalSinceNow: 0)
                         //时区
                         localNotification.timeZone = NSTimeZone .defaultTimeZone()
                         //推送内容
                         localNotification.alertBody = "获取时间成功:\(str)"
                         //声音
                         localNotification.soundName = UILocalNotificationDefaultSoundName
                         UIApplication .sharedApplication().scheduleLocalNotification(localNotification)
                         
                         //让OS知道已经获取到新数据
                         completionHandler( UIBackgroundFetchResult . NewData )
                         //completionHandler(UIBackgroundFetchResult.NoData)
                     }
             }) as NSURLSessionTask
             
             //使用resume方法启动任务
             dataTask.resume()
     }



5,后台获取测试 


(1)模拟器测试的话,只要选择Xcode 菜单栏的 Debug下的 Simulate Background Fetch即可 


(2)真机调试,如果没有连着电脑有时候等了一天才发生后台获取。连着电脑可能等个几分钟就能获取。