Apple 推送通知 (APN) 不一致?

2024-04-19

通过 APN 使用 Apple 的推送通知时,我们遇到了一个令人困惑的问题。我们有以下场景(我猜是相当标准的):

当我们的应用程序(我们在这里称之为“MyApp”)首次安装并启动时,我们会请求用户授予通过“MyApp”向他发送推送通知的权限。

在此示例中,AppDelegate 如下所示:

import UIKit
import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // Register Remote Notifications
        UNUserNotificationCenter.current().delegate = self
        self.registerForPushNotifications()

        return true
    }

    // MARK: - Remote Notifications

    func registerForPushNotifications() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
            guard granted else {
                return
            }
            self.getNotificationSettings()
        }
    }

    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            guard settings.authorizationStatus == .authorized else {
                return
            }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    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("ApnToken: \(token)")
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("did Fail to Register for RemoteNotifications")
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("willPresentNotification!")
        completionHandler([.badge, .sound, .alert])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("UserDidResponseToNotification!")
        completionHandler()
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("DidReceiveRemoteNotification!")
        completionHandler(.newData)
    }
}

因此,用户安装并启动应用程序,并询问是否允许“MyApp”向用户发送推送通知。如果用户接受推送通知application(_:didRegisterForRemoteNotificationsWithDeviceToken:)被调用,我们将收到的 deviceToken 提供给我们的 API。

现在让我困惑的部分是:

用户还可以选择稍后通过 iPhone 设置关闭推送通知,如下所示:设置 >“MyApp”> 通知 > 允许通知 > 关闭开关

我们的 API 现在拥有 APN 的 deviceToken,但用户通过 iPhone 设置关闭了推送通知。

问题”:

用户关闭推送通知后,我们仍然能够向设备发送静默推送通知,并且“MyApp”可以毫无问题地获取正确的数据。

但在另一种情况下:用户安装并启动“MyApp”并在第一次启动时拒绝推送通知,则无法从 Apple 获取 deviceToken。即使用户拒绝推送通知警报,我也尝试从 Apple 获取 deviceToken,如下所示:(但这不起作用 - 我猜如果用户拒绝,Apple 不会提供我的任何设备令牌)

func registerForPushNotifications() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
            self.getNotificationSettings()
        }
    }

    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { (settings) in
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    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("ApnToken: \(token)")
    }

如果用户在第一次启动时接受推送通知,那么他做什么似乎并不重要。我的意思是,好吧,我们无法通过横幅或任何内容向用户显示信息,但我们可以使用 APN 将数据传输到设备,即使用户稍后确实关闭了此设置。 (但是如果他在应用程序启动时拒绝,我们就无法发送任何内容 - 我们需要一个 deviceToken 一次)

我在这里误解了一件事吗?这对我来说似乎不一致。

我试图澄清我的问题,以便每个人都能理解我的要求。请原谅我的“糟糕”英语,作为一个非母语人士,在这里提出具有大量上下文的具体问题并不容易。无论如何,如果您需要更多信息,或者您不明白我所问的一个或多个要点,请告诉我,我将提供详细信息并澄清我的问题。

我不知道这是否重要,但目前我们正在使用 APN 开发证书(还不是分发证书)


好问题,

问题是,如果用户允许您发送推送通知(向您提供他/她的设备令牌),您将能够发送推送。通过通知的推送数据可以在不通知用户的情况下发送(静默通知),您可以在此处阅读更多相关信息:https://medium.com/@m.imadali10/ios-silent-push-notifications-84009d57794c https://medium.com/@m.imadali10/ios-silent-push-notifications-84009d57794c

这就是为什么即使用户阻止显示通知,您也能够发送推送。该设置仅控制显示外观,但由于他/她为您提供了令牌,您仍然可以向他们发送数据。实际上,用户在授予令牌后无法禁用该令牌。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Apple 推送通知 (APN) 不一致? 的相关文章

  • 如何在iOS中查找文本段范围

    如何在 iOS 中找到文本段 又名代码段 范围 意思是 文本段的起始地址和结束地址是多少 I found 这个有趣的帖子 http www pschweitzer fr p 12但它适用于 Android 但不适用于 iOS 经过一些挖掘和
  • 如何使用 AppDelegate 在视图之间共享 iAd 横幅

    我希望在我的应用程序中实现 iAd 到目前为止 我已经成功地使用下面的方法让它们在每个视图中正确显示 关闭 应用程序委托 import UIKit import iAd UIApplicationMain class AppDelegate
  • 无效的捆绑包...包含不允许的文件“frameworks”

    我尝试通过应用程序加载器发布我的应用程序 但我不断收到此错误 我试过了这个解决方案 https stackoverflow com questions 25777958 validation error invalid bundle the
  • 具有图形样式的 DatePicker 打破了 iOS 16.0 上的布局限制

    以下代码在 iOS 16 0 的 Xcode 14 0 0 Beta 5 上运行时打破了布局约束 struct ContentView View State var date Date var body some View DatePick
  • WKWebView不加载https URL?

    我有一个 WKWebView 应该加载以下网址 https buchung salonmeister de place offer details page id 907599 venueId 301655 她是我使用的代码 import
  • IOS 应用程序提交导出合规性:Firebase

    我准备将我的应用程序提交到应用程序商店 经过一些研究后 我似乎仍然无法在我的应用程序中找到有关 firebase 的任何信息 Firebase 是否可以豁免 我只用它来进行分析和 Admob 那么 Firebase 是否使用加密 如果使用
  • Firebase queryOrderedbyChild 不返回 Null 值

    我有一个根据年龄搜索用户的查询 self ref child users queryOrdered byChild age queryStarting atValue 18 queryEnding atValue 25 observeSin
  • 如何将动画应用到 GMSMarker

    我正在通过使用适用于 iOS V1 1 0 的 Google Maps SDK 将 iOS 地图迁移到 google 地图来更改我的应用程序 并且我尝试在添加 删除时对标记进行动画处理 但我在与此相关的文档中没有找到任何建议 请建议我如何在
  • 将 Google 登录与两个目标结合使用

    我有一个问题一直无法解决 我到处都在寻找 我最近将 Google Sign in 添加到我的应用程序中 并且它在主目标上运行良好 但是 由于我使用多个目标来部署应用程序的辅助版本 因此无法将第二个包标识符添加到 GoogleService
  • 更改 UIImageView 的位置

    我怎样才能为 UIImageView 做一个简单的位置改变 假设当前坐标是 x 20 和 y 30 我想将其移至 x 100 和 y 100 可以制作运动动画吗 你需要改变它的CGFrameUIImageView就像这样 imageView
  • _ 和 self 之间的区别。在 Objective-C 中

    使用下划线和使用selfObjective C 中调用时的关键字 property 财产申报 property weak nonatomic NSString myString Calling synthesize关于物业 synthesi
  • 如何更改 MGLPolyline 的颜色?

    如何更改 MGLPolyline 的颜色 我曾经看过here https stackoverflow com questions 32024464 customize mglpolyline using mapbox但答案不起作用 我还尝试
  • [项目] 的 Xcode 功能警告可能无法正常运行,因为其权利使用占位符团队 ID

    我是 Xcode 新手 刚刚启动一个单视图项目并遇到以下错误 项目名称 完美音调 Xcode版本 10 2 1 操作系统版本 10 14 5 1 Capabilities for Pitch Perfect may not function
  • 如何在 Swift 3 iOS 10 中创建自定义相册

    这听起来可能是重复的 但经过搜索 我仍然没有得到 Swift 3 的预期答案 当我尝试使用添加资产时为资产创建占位符后addAssets 方法 Xcode 建议我将 assetPlacehoder 转换为 FastEnumeration 类
  • 动态图标 iOS [重复]

    这个问题在这里已经有答案了 可能的重复 每天更改图标 https stackoverflow com questions 4038305 changing icon per day 如何制作动态图标 例如在日历中 每天该数字都会更改为当前值
  • 在自定义对象中映射 JSON 对象

    我一直在搜索是否可以获取 JSON 字典或数组并将其直接映射到属性与 JSON 标签同名的自定义对象中 但我没有找到任何相关信息 我一直在手动解析 JSON 字典 如下所示 id deserializedObj nil id jsonObj
  • Phonegap - navigator.app.backHistory() 不适用于 HTML 后退按钮

    在我的应用程序中 我使用phonegap 2 6 对于后退按钮 我使用以下函数 document addEventListener backbutton onBackKeyDown false function onBackKeyDown
  • NSData 不接受有效的 base64 编码字符串

    我正在 iOS 7 客户端实现 JSON Web Token 身份验证 效果很好 我的应用程序接收令牌 并可以使用它们对我的服务器进行经过身份验证的调用 现在 我希望我的客户端代码检查令牌的过期日期 以便它知道何时重新进行身份验证 检查 J
  • 如何检查 iOS 分发配置文件是否启用了推送通知?

    我有一个应用程序应该启用推送通知 但由于某种原因没有启用它们 我见过其他人下载并安装了该应用程序 但它甚至没有提示他们授予发送推送通知的权限 正如预期的那样 此应用程序不会出现在其 设置 gt 通知 中 但是 在我的 iPad 上 我能够从
  • 错误 ITMS-90207 Apple Store 提交

    当我在模拟器或设备上运行我的应用程序时 用于调试和发布构建配置 它可以完美运行 但是当我尝试将我的应用程序提交到 Apple Store 时 出现以下错误 错误 ITMS 90207 捆绑包无效 APPNAME app 处的捆绑包确实 不包

随机推荐

  • 使用反射设置枚举

    如何使用反射设置枚举 我的班级有枚举 public enum LevelEnum NONE CRF SRS HLD CDD CRS 在运行时我想将该枚举设置为 CDD 例如 我该怎么做 尝试使用类枚举 LevelEnum s LevelEn
  • Python 中的基本转换器

    我正在编写一个程序 用于在 Python 中将任何基数转换为基数 10 该程序的代码如下所示 print Enter the number you want to convert to base 10 number input length
  • 如何将 CLOB 数据从一个数据库传输到另一个具有 DBLinks 的远程 ORACLE 数据库

    问题是 如何将 CLOB 数据从一个源数据库传输到另一个具有 DBLink 的 Oracle 数据库 Oracle无法使用DBLinks传输CLOB数据 那么除了 将Oracle中的字段扩展为Varchar2 32 767个字符 Oracl
  • Javascript - 在 ES5 中扩展 ES6 类

    我正在使用以下代码作为滑块Siema https pawelgrzybek github io siema https codepen io pawelgrzybek pen boQQWy https codepen io pawelgrz
  • 命令提示符中的代码在批处理文件中不起作用

    当我在命令提示符中执行下面的代码时 它会执行我想要的操作 但当我将其放入 bat 文件并尝试执行它时 它不会执行我想要的操作 for f a in dir b csv do for f tokens b in a do echo b a g
  • jQuery - 如何将多个节点附加到容器

    我需要将多个节点附加到容器中 我不想在每次迭代中执行缓慢的 DOM 追加 而是想将文档片段中的节点排队 对其他想法开放 并一次将它们全部追加 这是我的代码 var fragment document createDocumentFragme
  • macOS Sierra 安装 PHP 扩展 intl

    我正在尝试让 magento 2 x 在我的机器上运行 我在用xampp 5 6使用相同的 php 版本并运行虚拟 apache 服务器 As seen in this screenshot The PHP Extension intl i
  • 在全局范围内声明命名空间错误

    我有 3 个文件 Test h Test cpp 和 main cpp Test h ifndef Test H define Test H namespace v int g 9 class namespce public namespc
  • 响应式表格,智能方式

    我有一个包含数据的表 表格数据 它看起来像这样 See 这把小提琴 http jsfiddle net MrLister c54RN 现在我想要的是 当它显示在较窄的屏幕上时 表格看起来像这样 这样你就不会得到水平滚动条并且它保持相同的视觉
  • 尝试使用锐利的 Node.js 调整流图像的大小

    我正在尝试使用锐利功能调整从用户到服务器的输入流图像的宽度和高度 但图像没有任何反应 它保持原来的大小 我应该如何使用锐化功能 以便我可以使图像变小或变大 请帮我 这就是我的代码的样子 use strict const builder re
  • 比较堆栈中的两个值? [复制]

    这个问题在这里已经有答案了 我卡住了 在我的汇编代码中 我想比较两个值 堆 x86 语法 AT T cmpl 4 ebp 4 ebp 错误 cmp 的内存引用太多 我认为不可能根据乘数和 ebp 来比较两个值 有什么建议 您可以使用 CMP
  • 如何将空白复选框作为 false 传递给参数

    我有一个更新用户表单的表单 其中几个元素是复选框 我希望 true 传递给参数 如果选中 这是工作 false 传递给参数 如果未选中 不工作 未经检查的项目甚至没有发送到参数 如何使未检查的项目作为错误通过 Form h4 Please
  • Junit 异常测试用例 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 public class TipException extends Exception private final Object mSour
  • Python ARIMA模型,预测值发生偏移

    我是 Python ARIMA 实现的新手 我有几个月 15 分钟一次的数据 我尝试遵循 Box Jenkins 方法来拟合时间序列模型 我在最后遇到了一个问题 这ACF PACF图 https i stack imgur com weNJ
  • Haskell 中自动函数约束推导的类型约束

    出于教育目的 我在 Haskell 中摆弄树木 我有Tree a像这样定义的类型 data Tree a EmptyTree Node a Tree a Tree a 以及许多共享基本约束的函数 Ord a 所以他们有这样的类型 treeI
  • 无法点击 iframe 内的按钮

    设想 Launch http www indiabookstore net http www indiabookstore net 点击FB 类似按钮它位于 iframe 内 向下滚动即可看到 Issue 我可以切换到 iframe 但无法
  • Android 上的图像处理 - 我可以使用哪些库?

    我专门需要它来处理图像失真 滤镜 模糊等 也欢迎 你知道一些我可以使用的具有适当许可证的库 还有 Apache MIT LGPL 吗 价格合理的专有图书馆 也向他们开放 也可以用C语言 提前致谢 达内尔 您可能想查看OpenCV http
  • 我的 Web API 序列化出现错误

    我有一个带有多个返回不同结果的控制器的 WebApi 例如 一个控制器返回了IEnumerable
  • ImportError:LinuxMint17.3 中“没有名为plotly.plotly 的模块”

    每当我尝试编译以下代码以获得折线图时 都会显示一些错误 但我不知道如何解决它 这是我的code https plot ly python line charts import plotly plotly as py import plotl
  • Apple 推送通知 (APN) 不一致?

    通过 APN 使用 Apple 的推送通知时 我们遇到了一个令人困惑的问题 我们有以下场景 我猜是相当标准的 当我们的应用程序 我们在这里称之为 MyApp 首次安装并启动时 我们会请求用户授予通过 MyApp 向他发送推送通知的权限 在此