Swift 中的后台处理
Background Processing in Swift
I Switched to push notifications, check my answer below.
我正在尝试实现一个 运行 在应用程序置于后台时在后台执行的功能。该实现类似于一个计时器,当我们退出应用程序时,该计时器必须保持 运行ning。我已经在我的应用程序中激活了 "Background Processing",这是我想要在后台 运行 的功能:
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 . then you can follow exactly the instructions here to create and deploy your flask application: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-04 的 5 欧元/月 ubuntu 服务器(这些说明适用于任何 ubuntu 服务器,并且他们还有针对不同 OS).
将 flask 配置为服务器:https://firebase.google.com/docs/admin/setup
DISCLAIMER: you should't proceed if you haven't follow successfully the previous steps.
现在,如果您是 Flask 的新手,它会非常巧妙地处理 HTTP 请求,而且非常直观。
4.1。打开你的烧瓶应用程序进行编辑 nano myproject.py
或 vim myproject.py
等
4.2 在您的导入中添加 import requests
和 from pyfcm import FCMNotification
,并在导入之后添加:push_service = FCMNotification(api_key=SERVER_KEY)
其中 SERVER_KEY
是项目设置中来自 firebase 的服务器密钥。
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
或者您可以使用您的服务器 public IP 地址而不是域,如果您没有.
- 如果您没有 SSL 证书(您使用的是
http
而不是 https
),则必须返回 Xcode 并在您的Info.plist
:
- 转到您的
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.
}
- 最后,在 Xcode 中,您可以这样调用
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()
I Switched to push notifications, check my answer below.
我正在尝试实现一个 运行 在应用程序置于后台时在后台执行的功能。该实现类似于一个计时器,当我们退出应用程序时,该计时器必须保持 运行ning。我已经在我的应用程序中激活了 "Background Processing",这是我想要在后台 运行 的功能:
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 . then you can follow exactly the instructions here to create and deploy your flask application: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-04 的 5 欧元/月 ubuntu 服务器(这些说明适用于任何 ubuntu 服务器,并且他们还有针对不同 OS).
将 flask 配置为服务器:https://firebase.google.com/docs/admin/setup
DISCLAIMER: you should't proceed if you haven't follow successfully the previous steps.
现在,如果您是 Flask 的新手,它会非常巧妙地处理 HTTP 请求,而且非常直观。
4.1。打开你的烧瓶应用程序进行编辑
nano myproject.py
或vim myproject.py
等4.2 在您的导入中添加
import requests
和from pyfcm import FCMNotification
,并在导入之后添加:push_service = FCMNotification(api_key=SERVER_KEY)
其中SERVER_KEY
是项目设置中来自 firebase 的服务器密钥。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
或者您可以使用您的服务器 public IP 地址而不是域,如果您没有.
- 如果您没有 SSL 证书(您使用的是
http
而不是https
),则必须返回 Xcode 并在您的Info.plist
:
- 转到您的
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.
}
- 最后,在 Xcode 中,您可以这样调用
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()