- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用的是 Xcode 版本 9.4.1 (9F2000)
。
我在AppDelegate.swift
中有这段代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
showPushButtons()
return true
}
func httpRequest(file: String, postKey1: String, postValue1: String, postKey2: String, postValue2: String) {
let url = URL(string: "https://www.example.com/\(file)")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "\(postKey1)=\(postValue1)&\(postKey2)=\(postValue2)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
}
func showPushButtons(){
let replyAction = UNTextInputNotificationAction(
identifier: "reply.action",
title: "Reply to message",
textInputButtonTitle: "Send",
textInputPlaceholder: "Write some text here")
let pushNotificationButtons = UNNotificationCategory(
identifier: "allreply.action",
actions: [replyAction],
intentIdentifiers: [],
options: [])
UNUserNotificationCenter.current().setNotificationCategories([pushNotificationButtons])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "reply.action" {
if let textResponse = response as? UNTextInputNotificationResponse {
let sendText = textResponse.userText
print("Received text message: \(sendText)")
httpRequest(file: "message.php", postKey1: "message", postValue1: "Hello!", postKey2: "chat_user", postValue2: "Peter")
}
}
completionHandler()
}
它的作用:
当收到推送通知并用力触摸时,将会出现一个文本字段和键盘(如 WhatsApp 等消息应用程序所示)。您可以编写一些文本并提交/发送。
您可以使用此行获取并打印提交的消息:
print("收到短信:\(sendText)")
这工作正常,没有任何问题。
但是当尝试像这样将数据发送到我的服务器时:
httpRequest(file: "message.php", postKey1: "message", postValue1: "Hello!", postKey2: "chat_user", postValue2: "David")
它不工作。无法访问我的服务器,并且我在控制台日志中收到如下错误:
Received text message: First try
2018-07-19 08:45:00.643935+0200 MyApp[4307:1502538] +[CATransaction synchronize] called within transaction
2018-07-19 08:45:00.644639+0200 MyApp[4307:1502538] +[CATransaction synchronize] called within transaction
2018-07-19 08:45:13.091958+0200 MyApp[4307:1502647] TIC TCP Conn Failed [1:0x1c4169a80]: 1:50 Err(50)
2018-07-19 08:45:13.093089+0200 MyApp[4307:1502647] Task <1E8151BB-7098-46CD-9F68-8AA0E320CB7D>.<1> HTTP load failed (error code: -1009 [1:50])
Received text message: Second try
2018-07-19 08:45:13.094756+0200 MyApp[4307:1503029] Task <1E8151BB-7098-46CD-9F68-8AA0E320CB7D>.<1> finished with error - code: -1009
2018-07-19 08:45:13.096208+0200 MyApp[4307:1502538] +[CATransaction synchronize] called within transaction
2018-07-19 08:45:13.096580+0200 MyApp[4307:1502538] +[CATransaction synchronize] called within transaction error=Optional(Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSUnderlyingError=0x1cc047320 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=https://www.example.com/message.php, NSErrorFailingURLKey=https://www.example.com/message.php, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=50, NSLocalizedDescription=The Internet connection appears to be offline.})
我的函数 httpRequest()
似乎可以工作,因为我可以从 didFinishLaunchingWithOptions
调用它,如下所示:
httpRequest(file: "message.php", postKey1: "message", postValue1: "Hello!", postKey2: "chat_user", postValue2: "David")
没有任何问题。这也意味着我的域和服务器工作正常。
但是为什么我无法从 UNUserNotificationCenter
函数调用我的 httpRequest()
函数?
当收到推送通知时,我的应用程序当然处于后台或关闭状态。我是否需要一些特殊的代码才能使其在后台模式下工作?
最佳答案
这是我来自 AppDelegate.swift
的工作代码:
// AppDelegate.swift
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
pushAction()
return true
}
func registerForPushNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
print("\nPermission granted: \(granted)\n")
self.pushAction()
guard granted else { return }
self.getNotificationSettings()
}
}
func getNotificationSettings() {
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
print("\nNotification settings: \(settings)\n")
guard settings.authorizationStatus == .authorized else { return }
DispatchQueue.main.async(execute: {
UIApplication.shared.registerForRemoteNotifications()
})
}
}
func httpRequest(file: String, postKey1: String, postValue1: String, postKey2: String, postValue2: String) {
let url = URL(string: "https://www.example.com/\(file)")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "\(postKey1)=\(postValue1)&\(postKey2)=\(postValue2)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("\nerror=\(String(describing: error))\n")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
print("\nstatusCode should be 200, but is \(httpStatus.statusCode)\n")
print("\nresponse = \(String(describing: response))\n")
}
let responseString = String(data: data, encoding: .utf8)
print("\nresponseString = \(String(describing: responseString))\n")
}
task.resume()
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data -> String in
return String(format: "%02.2hhx", data)
}
let token = tokenParts.joined()
print("\nDevice Token: \(token)\n")
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("\nFailed to register: \(error)\n")
}
func pushAction(){
let replyAction = UNTextInputNotificationAction(
identifier: "reply.action",
title: "Reply to message",
options:[],
textInputButtonTitle: "Send",
textInputPlaceholder: "Input/write text here")
let pushNotificationButtons = UNNotificationCategory(
identifier: "allreply.action",
actions: [replyAction],
intentIdentifiers: [],
options: [])
UNUserNotificationCenter.current().setNotificationCategories([pushNotificationButtons])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// If you don’t want to show notification when app is open, do something else here and make a return here.
// Even if you don’t implement this delegate method, you will not see the notification on the specified controller. So, you have to implement this delegate and make sure the below line execute. i.e. completionHandler.
completionHandler([.sound,.alert,.badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "reply.action" {
if let textResponse = response as? UNTextInputNotificationResponse {
if UIApplication.shared.applicationState != .active{
self.registerBackgroundTask()
}
let sendText = textResponse.userText
print("\nReceived text message: \(sendText)\n")
DispatchQueue.global(qos: .background).async {
self.httpRequest(file: "message.php", postKey1: "message", postValue1: sendText, postKey2: "user", postValue2: "Peter")
}
}
}
completionHandler()
}
func registerBackgroundTask() {
backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
self?.endBackgroundTask()
}
assert(backgroundTask != UIBackgroundTaskInvalid)
}
func endBackgroundTask() {
print("\nBackground task ended.\n")
UIApplication.shared.endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
}
不要忘记:
-创建推送证书
– 您将在控制台日志中看到您的设备 token
– 在您的 aps 有效负载中添加 "category":"allreply.action"
,如下所示:
{
"aps":{
"alert":{
"title":"Hello",
"body":"This is a test!"
},
"badge":0,
"sound":"default",
"category":"allreply.action"
}
}
在功能
中启用推送通知
和后台模式
:
关于ios - swift ;来自 UNUserNotificationCenter 的 HTTP 请求不起作用 : The Internet connection appears to be offline,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51377167/
按照文档的要求,如果它们在同一个线程上,则一个接一个地删除和添加具有匹配标识符的通知对我来说似乎工作正常。如果它们在不同的线程上,则新添加的通知将被上一行的 delete 调用删除。第一个案例保证有效
我正在尝试使用适用于 iOS 10 的 UserNotifications 框架。 如果我不传入触发器,通知似乎工作得很好。它们会立即出现在应用程序中。但我需要为触发器传递一个延迟。谁能看到我的代码中
我有一个用 Swift 编写的应用程序,它使用 UNUserNotificationCenter,当该应用程序位于前台时,它会显示通知。 我想做的是在通知已发送且应用程序位于前台后更新 UI 以下显示
我有一个 Xcode 项目,Xcode 8.1 (8B62),有两个目标,一个用于应用程序的付费版本,另一个用于免费版本。他们都管理远程推送通知。由于我使用新框架 UNUserNotification
我想在应用程序处于前台时显示推送通知的横幅。我实现了这个方法来显示通知: func userNotificationCenter(_ center: UNUserNotificationCenter,
运行下面的代码不会在屏幕右上角显示通知(作为横幅或警报)。通知显示在通知中心。 我确保我的系统上禁用了“请勿打扰”。我还尝试了系统偏好设置 -> 通知 -> 我的应用程序名称中的“横幅”和“警报”设置
我使用的是 MacOS Mojave,并且从使用现已弃用的 NSUserNotification 切换到 UNUserNotificationCenter。我的应用程序出现在系统偏好设置通知中,并选择
我刚刚对 iOs 10 和其他版本的通知进行了更改: if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.cu
我现在如何调用本地通知?而不是在未来设定一个时间间隔?此代码将在未来 5 秒后显示通知。我希望现在就调用它。 let trigger = UNTimeIntervalNotificationTrigg
如果服务器向用户发送推送通知,但用户没有点击该通知,应用程序仍然可以确定有推送发送到手机并使用 UNUserNotificationCenter.getDeliveredNotifications()
有几篇文章解决了同样的问题,但(据我所见)它们都是 4 年前的,而且是在 Objective-C 中。我正在使用 Swift 4.2。 我正在制作一个倒计时应用程序。当应用程序在后台并且计时器到期时,
我正在使用 Apple 去年在 iOS 10 中宣布的一项功能。我的问题是通知中的图像有时是空的。 这是我的UNNotificationServiceExtension..我不确定我做错了什么。图像的
我正在使用 UNUserNotificationCenter.App 创建警报当应用程序处于后台或退出时效果很好但是,如果应用程序正在运行,则不会发出警报。 我听说应用程序运行时没有警报。是真的吗?
我在应用程序中使用本地通知时遇到问题。 我正在安排包含自定义内容和自定义操作类别的本地通知。它在 iOS 11 中进行调度和触发,但在 iOS 10 中没有。 根据文档,它应该也适用于 iOS 10。
当我发送推送通知时,应用程序在前台 willPresent 被调用。 didReceive 永远不会被调用。当应用程序在后台并收到推送通知时,会显示警报,但应用程序不会调用 didReceive 或
我正在尝试制作一个提醒应用,并且我所有的通知重复都设置为 true Example : var dateComponents = DateComponents() da
我正在安排本地通知。它适用于 iOS 9.x,但自 iOS 10 以来 -(void)application:(UIApplication *)application didReceiveLocalN
我的 AppDelagate 中有以下代码块: func userNotificationCenter(_ center: UNUserNotificationCenter,
我正在尝试检索仍显示在通知中心的所有已发送通知,但 UNUserNotificationCenter getDeliveredNotifications(completionHandler:) 不起作
我正在处理本地通知,但我遇到的问题是当应用程序终止时没有调用 didReceive Response 方法,所以当我点击通知操作时它只是启动应用程序而没有做任何其他事情。但是,当该应用程序仅在后台运行
我是一名优秀的程序员,十分优秀!