iOS 后台 post 请求静默通知
iOS background post request on silent notification
我想问一下,当应用程序收到静默推送通知时,是否可以从应用程序发送URLPOST请求。如果可以,我怎样才能得到它?
我的应用程序成功接收静默推送通知并且当我插入phone时Xcode我能够执行url任务 (即使在背景中)并获得所需的结果。 从我的 Mac 上拔下 phone 后,phone 完全停止执行 url 任务 。
关于apple documentation,当静默推送通知出现时,我有30秒的时间来执行代码
Your app has 30 seconds to perform any tasks and call the provided completion handler
我的静默推送通知:
{
notification: {},
apns: {
headers: {
"apns-priority" : '5',
"apns-push-type" : 'background'
},
payload: {
aps: {
"content-available" : 1,
}
}
},
topic: topic
};
AppDelegate.swift:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
guard (userInfo["aps"] as? [String?: Any]) != nil else {
Analytics.logEvent("fetch_failed", parameters: nil)
completionHandler(.failed)
return
}
self.emailFetch() // Here I call my function for sending POST request via URLSession
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
已解决
目前我已将 dataTask 更新为 downloadTask,现在我能够从临时文件中成功读取服务器的答案。当应用程序在后台 运行 时,它可以正常工作。
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
guard (userInfo["aps"] as? [String?: Any]) != nil else {
Analytics.logEvent("fetch_failed", parameters: nil)
completionHandler(.failed)
return
}
if login != nil && password != nil {
let session = URLSession.shared
let url = URL(string: "https://....")!
let body_values = Data(("data...").utf8)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36", forHTTPHeaderField: "User-Agent")
request.httpBody = body_values
print("Starting load data")
let loadDataTask = session.downloadTask(with: request) { data, response, error in
if let httpResponse = response as? HTTPURLResponse {
print(httpResponse.statusCode)
if httpResponse.statusCode == 200 {
if let data = data {
if let dataString = try? String(contentsOf: data) {
This is being executed only in XCode
My logic is here...
completionHandler(.newData)
} else {
completionHandler(.failed)
}
}
else {
completionHandler(.failed)
}
}
else {
completionHandler(.failed)
}
}
else {
completionHandler(.failed)
}
}
loadDataTask.resume()
}
else {
completionHandler(.failed)
}
}
嗨,Peter 不确定您是否想过这个问题,但基本上您必须在 URLSession 中使用 .downloadTask 而不是 .dataTask。这可能就是您当前的解决方案不起作用的原因。倾向于认为“这不是下载任务”,而只是原理图问题。将下载视为来自服务器的响应(例如 200“成功”)。您仍然可以 POST 使用此方法。
我想问一下,当应用程序收到静默推送通知时,是否可以从应用程序发送URLPOST请求。如果可以,我怎样才能得到它?
我的应用程序成功接收静默推送通知并且当我插入phone时Xcode我能够执行url任务 (即使在背景中)并获得所需的结果。 从我的 Mac 上拔下 phone 后,phone 完全停止执行 url 任务 。
关于apple documentation,当静默推送通知出现时,我有30秒的时间来执行代码
Your app has 30 seconds to perform any tasks and call the provided completion handler
我的静默推送通知:
{
notification: {},
apns: {
headers: {
"apns-priority" : '5',
"apns-push-type" : 'background'
},
payload: {
aps: {
"content-available" : 1,
}
}
},
topic: topic
};
AppDelegate.swift:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
guard (userInfo["aps"] as? [String?: Any]) != nil else {
Analytics.logEvent("fetch_failed", parameters: nil)
completionHandler(.failed)
return
}
self.emailFetch() // Here I call my function for sending POST request via URLSession
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
已解决
目前我已将 dataTask 更新为 downloadTask,现在我能够从临时文件中成功读取服务器的答案。当应用程序在后台 运行 时,它可以正常工作。
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
guard (userInfo["aps"] as? [String?: Any]) != nil else {
Analytics.logEvent("fetch_failed", parameters: nil)
completionHandler(.failed)
return
}
if login != nil && password != nil {
let session = URLSession.shared
let url = URL(string: "https://....")!
let body_values = Data(("data...").utf8)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36", forHTTPHeaderField: "User-Agent")
request.httpBody = body_values
print("Starting load data")
let loadDataTask = session.downloadTask(with: request) { data, response, error in
if let httpResponse = response as? HTTPURLResponse {
print(httpResponse.statusCode)
if httpResponse.statusCode == 200 {
if let data = data {
if let dataString = try? String(contentsOf: data) {
This is being executed only in XCode
My logic is here...
completionHandler(.newData)
} else {
completionHandler(.failed)
}
}
else {
completionHandler(.failed)
}
}
else {
completionHandler(.failed)
}
}
else {
completionHandler(.failed)
}
}
loadDataTask.resume()
}
else {
completionHandler(.failed)
}
}
嗨,Peter 不确定您是否想过这个问题,但基本上您必须在 URLSession 中使用 .downloadTask 而不是 .dataTask。这可能就是您当前的解决方案不起作用的原因。倾向于认为“这不是下载任务”,而只是原理图问题。将下载视为来自服务器的响应(例如 200“成功”)。您仍然可以 POST 使用此方法。