【问题标题】:iOS Notification when App is in Background应用程序处于后台时的 iOS 通知
【发布时间】:2016-02-13 16:55:20
【问题描述】:

我想知道是否可以在 iOS 中启动后台进程。在我的后台进程中,每 30 分钟应该调用一个函数,以便检查我的数据库中是否有新消息等,以便发送通知。我不想实现推送通知。 我不知道在哪里实现此功能,以及是否有覆盖功能,例如在 AppDelegate 中。

感谢您的帮助, 汉尼斯

【问题讨论】:

标签: ios swift notifications background-process


【解决方案1】:

你想要的叫做“后台获取”,从 iOS 7 开始就可以使用:

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

【讨论】:

  • 应该注意的是,“后台获取”并不保证按照 OP 的要求每 30 分钟运行一次。
  • OP 要求的内容不存在。唯一的其他选择是推送通知 - 然后您拥有更大的控制权。但是对于推送通知,也没有 30 分钟的保证。
  • 这是真的,@Darko。但是如果你提出什么建议,你也应该提到你的建议不满足“每 30 分钟运行一次代码”的条件。
【解决方案2】:

是的,可以在 iOS 中启动后台进程。也可以每 30 分钟启动一次此过程。你需要设置两件事!您需要每 30 分钟向您的服务器发送一次静默推送。(例如,在 Parse 中使用 Cloud Code 作业(警告!由于 Parse 将于 2017 年 1 月关闭,因此在此平台上工作并不聪明)

这种静默推送会启动一个 NSURLBackgroundSession,它会从您的服务器中提取所需的数据并进行处理。

Your need to activate this in the project settings

1.) 在 AppDelgate 中添加这个来接收推送

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

当你从服务器或其他东西获得推送时,将调用以下委托方法:(所以在你的 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...
     }

现在调用的方法需要从数据库中提取数据。在这种情况下,您使用 NSURLSession 来下载您需要的任何内容。

2.) 转到处理数据的 ViewController 并添加: 具有所需委托方法的 NSURLSessionDownloadDelegate 委托

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()
}
}

当下载任务成功完成时

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

将被调用,您可以处理数据

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

您也可以使用 NSURLSessionDataTask 来执行此操作

【讨论】:

  • 2 注意事项:第一:没有必要在“项目功能”下的“后台模式”下检查“后台获取”。对于这种情况,“远程通知”检查就足够了。第二:在使用 Parse 作为服务器之前,您可能要三思而后行,因为 Facebook 宣布将在 2017 年 1 月将其关闭。它现在是开源的,您可以自己托管它,但在使用之前请三思。
  • 是的,你完全正确。我刚刚提到了 Parse,所以你可以大致想象我的意思。
【解决方案3】:

我建议你看看Apple's documentation on Background Execution。它说明了在后台运行代码的所有可能方式。每种方法都有其局限性、优点和缺点,还有Apple mentions:

在 iOS 中,只允许特定的应用类型在后台运行

如果您的 iOS 应用程序不通过蓝牙(BTLE 或通过 MFi 认证的设备)与某些设备进行通信(您可以将该蓝牙设备配置为每 30 分钟向 iOS 设备发送一些事件并在发生这种情况时执行您的代码),那么每 30 分钟运行一次代码的最可靠方法是使用静默推送通知。
可以配置静默推送通知,以便它们不会显示给用户,但允许您的代码运行。推送通知的限制是用户需要有效的互联网连接才能接收它们,并且用户需要授予您的应用使用推送通知的权限(您可以在应用首次运行时请求此权限)。
我注意到您的问题提到我不想使用推送通知,但不幸的是,您在这里没有选择。

【讨论】:

    【解决方案4】:

    作为背景

    在你的 viewDidLoad() 方法中

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

    在你的 ViewController 中添加这个方法

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

    前台

      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!")
    }
    

    【讨论】:

      猜你喜欢
      • 2017-02-04
      • 1970-01-01
      • 2012-09-09
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      相关资源
      最近更新 更多