更新
在发表一些评论后,我将resolveVisita
方法更改为在后台使用URLSession
,但看起来后台会话只会在应用程序位于前台时启动,这里是更新后的方法在点击通知操作时运行:
static func resolverVisita(idMensagem: String, resposta: String, liberar: Bool, view: UIViewController?) {
//let configuration = URLSessionConfiguration.background(withIdentifier: "url_session_resolve_visita")
//var backgroundSession = URLSession(configuration: configuration)
// Set up the URL request
let todoEndpoint: String = URL_RESPONDE_VISITA
guard let url = URL(string: todoEndpoint) else {
print("Error: cannot create URL")
return
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
let postString = "userUUID=\(SessionManager.getUsrUUID())&devUUID=\(devUUID)&msgID=\(idMensagem)&tarefa=\(liberar ? "L" : "B")&resposta=\(resposta)"
urlRequest.httpBody = postString.data(using: .utf8)
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).responde_visita")
let session = URLSession(configuration: config)
/*
let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}*/
let task = session.dataTask(with: urlRequest)
task.resume()
}
注释掉的代码似乎有时会起作用,但看起来它不是正确的方法。
更新结束
所以我有一个接收通知的应用程序,它有2个动作,并且在用户响应时,应用程序应该向服务器发送响应,最好是在后台。
我遇到一个问题,无论什么时候点击某个操作,有时在打开应用程序之前都不会调用userNotificationCenter
方法,有时它会运行,但是 Alamofire 服务器调用没有得到处理,然后如果我打开应用程序控制台中显示有关Alamofire调用的一些错误,但是如果我点击操作然后打开应用程序足够快它按预期工作。
我已经在Xcode的应用功能下启用了后台获取和远程通知。
这就是我为通知创建操作的方式:
let liberar = UNTextInputNotificationAction(identifier:"liberar", title:"Liberar",options:[.authenticationRequired],
textInputButtonTitle: "Liberar",
textInputPlaceholder: "Resposta")
let bloquear = UNTextInputNotificationAction(identifier: "bloquear", title: "Bloquear", options: [.destructive],
textInputButtonTitle: "Bloquear",
textInputPlaceholder: "Resposta")
这是我的UNUserNotificationCenterDelegate
协议实施:
extension AppDelegate : UNUserNotificationCenterDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([.alert, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
let acao = response.actionIdentifier
//let request = response.notification.request
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(acao)
if acao == "liberar" {
// Print full message.
let textResponse = response as! UNTextInputNotificationResponse
print("Liberando Visita")
AppConfig.resolverVisita(idMensagem: (userInfo["msgid"] as? String)!, resposta: textResponse.userText, liberar: true, view: nil)
}
else if acao == "bloquear" {
let textResponse = response as! UNTextInputNotificationResponse
print("Bloqueando Visita")
AppConfig.resolverVisita(idMensagem: (userInfo["msgid"] as? String)!, resposta: textResponse.userText, liberar: false, view: nil)
//let newContent = request.content.mutableCopy() as! UNMutableNotificationContent
//print(textResponse.userText)
}
completionHandler()
}}
这是resolveVisita
方法,它基本上只是收集一些数据并使用Alamofire通过POST请求发送。
static func resolverVisita(idMensagem: String, resposta: String, liberar: Bool, view: UIViewController?) {
if view != nil {
showLoading(mensagem: NSLocalizedString("Processando...", comment: ""), view: view!)
}
//Parameters to be sent
let parameters: Parameters=[
"userUUID":SessionManager.getUsrUUID(),
"devUUID":devUUID,
"msgID": idMensagem,
"resposta": resposta,
"tarefa": liberar ? "L" : "B"
];
//Sending http post request
Alamofire.request(URL_RESPONDE_VISITA, method: .post, parameters: parameters).responseJSON{
response in
//printing response
print(response)
//getting the json value from the server
if let result = response.result.value {
//converting it as NSDictionary
let jsonData = result as! NSDictionary
var mensagem : String = "Solicitacao resolvida com sucesso"
//displaying the message in label
if((jsonData["error"] as! Bool)){
mensagem = jsonData["error_msg"] as! String
if view == nil {
Notificacoes.notificaErroSolicitavao(msgId: idMensagem, errMsg: mensagem)
}
}
if view != nil {
view?.dismiss(animated: false){
showAlert(mensagem: NSLocalizedString(mensagem, comment: ""), view: view!, okMsg: NSLocalizedString("Voltar", comment: ""), segue: "voltarParaLogin")
}
}
else{
print(mensagem)
}
}
}
}
如果我只是将.foreground
选项添加到选择后打开应用程序的操作,问题就解决了,但我真的认为应用程序无需为此任务打开。< / p>
答案 0 :(得分:0)
所以过了一段时间我决定以一种清醒的头脑回到这个问题,我发现我做错了什么,我试图在后台创建URLSession
的实例锁定屏幕,并创建“同一会话”的新实例,以解决这个问题,我所要做的就是创建一个URLSession
的静态实例,然后在需要时使用它。
我是这样创造的。
static let resolveVisitaSession = URLSession(configuration: URLSessionConfiguration.background(withIdentifier: "br.com.freaccess.resolveVisitaRequest"))
这是在UNNotificationAction
上选择的方法,我在那里使用我的URLSession。
static func resolverVisita(idMensagem: String, resposta: String, liberar: Bool) {
print("Entered resolveVisita method")
// Set up the URL request
let todoEndpoint: String = URL_RESPONDE_VISITA
guard let url = URL(string: todoEndpoint) else {
print("Error: cannot create URL")
return
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
let postString = "userUUID=\(SessionManager.getUsrUUID())&devUUID=\(devUUID)&msgID=\(idMensagem)&tarefa=\(liberar ? "L" : "B")&resposta=\(resposta)&skipSocket=true"
urlRequest.httpBody = postString.data(using: .utf8)
resolveVisitaSession.dataTask(with: urlRequest).resume()
}