我已切换为推送通知,请在下面检查我的答案。
我正在尝试实现将应用程序置于后台时在后台运行的功能。该实现类似于计时器,当我们退出应用程序时,该计时器必须保持运行。我已经在我的应用程序中激活了“后台处理”,这是我想在后台运行的功能:
public func keepCheck(timer:Timer) {
DispatchQueue.global(qos: DispatchQoS.background.qosClass).async {
print("do some background task")
if self.check == true {
if self.outBool == false {
self.residualWaterWeight -= self.indoorDryRate
if self.residualWaterWeight <= 0.0 {
self.appDelegate?.scheduleNotification(notificationType: "Your Clothes are Dry!",body: "I Love fabric conditioner smell in the morning <3")
self.defaults.set(false, forKey: "keep_check")
}
print(self.residualWaterWeight)
} else {
self.do10min()
}
self.check = self.defaults.bool(forKey: "keep_check")
}
DispatchQueue.main.async {
print("update some UI")
}
}
}
现在,当打开应用程序时,此功能在后台运行,但是当您点击主页按钮时,它将停止。如何防止此功能在应用程序暂停时停止?
尽管不满意,我仍然认为我的解决方案对于iOS开发中的通知新手可能有用。我从本地通知切换为推送通知,将远程烧瓶应用程序设置为使用Firebase处理所有后台处理和通知发送:
按照本教程设置您的应用程序以接收推送通知:https://www.youtube.com/watch?v=34kvGKdPN2k
在远程服务器上创建一个flask应用程序并进行部署。如果您没有远程服务器,则使用https://www.digitalocean.com中每月5欧元的ubuntu服务器。那么您可以完全按照此处的说明创建和部署flask应用程序:https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-04(这些说明可在任何ubuntu服务器上运行,并且它们具有适用于不同OS的其他教程)。
使用Firebase作为服务器配置烧瓶:https://firebase.google.com/docs/admin/setup
免责声明:如果您未成功遵循前面的步骤,则不应继续。
现在,如果您不熟悉Flask,它可以非常整洁地处理HTTP请求,并且非常直观。
4.1。打开烧瓶应用程序以编辑nano myproject.py
或vim myproject.py
等。>
4.2在您的导入中添加import requests
和from pyfcm import FCMNotification
4.3添加以下代码(所有大写字母中的所有代码都可以更改):
@app.route('/MY_REQUEST_NAME')
def MY_FUNCTION():
# MY_ARGUMENT in this case will be the iOS device token
MY_ARGUMENT = str(request.args.get('MY_ARGUMENT'))
# do calculations
result = push_service.notify_single_device(registration_id=MY_ARGUMENT, message_title=MESSAGE, message_body=BODY)
return MY_RESULTS
# if you're goal is just sending notification you don't really need a return statement
4.4保存并退出,然后在服务器中激活虚拟环境source myprojectenv/bin/activate
并键入pip install requests pyfcm
Flask应用程序将触发我们在浏览器中输入的刚刚编写的功能:http://your_domain.com/my_request_name?my_argument=my_argument_value
;如果没有,则可以使用服务器的公共IP地址代替域。
AppDelegate
并修改以下功能以将设备fcm_token存储在某处。我个人使用了defaults.standard
:func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
// Save Token:
UserDefaults.standard.set(fcmToken, forKey: "FCM_TOKEN")
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
http
请求:let token = UserDefaults.standard.string(forKey: "FCM_TOKEN")!
let url : URL = URL(string: "http://your_domain.com/my_request_name?my_argument=\(token)")!
let task = URLSession.shared.dataTask(with: url)
task.resume()