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 上使用 Web 服务的最佳方式?

    我想构建一个 iOS 应用程序 让您登录到网络服务 之后 应用程序将 当用户选择时 通过 https 发送登录名 密码以及请求的变量 例如 在请求 新闻更新 后 它将收到 XML 格式的请求信息 类似于
  • 如何使用完成处理程序等待 firestore 请求的完成

    我正在慢慢地了解完成处理程序 如果我有一个 firestore 查询 如果我想使用完成处理程序 则有点向后工作 当 firestore 查询完成时 我必须使用completion 但它的设置功能仍然让我感到困惑 因此 如果这是一个将闭包作为
  • Swift:如何减少 didupdatelocations 调用

    我想出了一些代码来打印我所在位置的地址和邮政编码 这是在 didupdatelocation 函数中完成的 我遇到的唯一问题是 didupdatelocation 函数每秒都会更新该地址 因为这电池效率非常低 所以我一直在寻找使用间隔的方法
  • 在 IOS 上使用 AVComposition 混合两个音频文件

    我正在尝试混合两个音频文件 将一个音频文件放在另一个音频文件之上 不是缝合在一起 但我在 IOS 上学习 AVFoundation 时遇到了困难 我在这里遵循了这个答案 如何使用 AVMutableCompositionTrack 合并音频
  • 适用于 IOS 和 Android 的支付网关 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一个应用程序 用户必须在澳大利亚餐馆通过应用程序 android ios 付款 有两种付款方式 通过 PayPal 或 Visa
  • 在带有 Storyboard 的 XCode 4 中以模态方式推送视图时,出现“对开始/结束外观转换的不平衡调用”警告

    在网上进行了一些研究但没有成功后 我来这里向您询问有关我的警告的问题 实际上 我有一个带有导航控制器的视图 V1 我想在 V1 完成加载时推送模态视图 V2 所以我用performSegueWithIdentifier方法 我正在使用故事板
  • 为什么我不能在 Realm 属性上使用 private

    我正在尝试在 RealmSwift 中存储一个枚举案例 但 Realm 不支持枚举 本文 https medium com it works locally persisting swift enumerations with realm
  • 推入 UINavigationController 时隐藏 FBFriendPickerViewController 导航栏

    介绍一个实例FBFriendPickerViewController using presentViewController animated completion 非常简单 该类似乎是针对该用例的 但是 我想推送一个实例FBFriendP
  • PushSharp APNS 生产:无法识别提供给包的凭据(但开发工作正常)

    我的应用程序刚刚准备在 App Store 上销售 但我的生产设备 从 App Store 安装了该应用程序的设备 都没有收到推送通知 当我尝试向生产设备发送推送通知时 出现以下错误 The credentials supplied to
  • iOS 中的构建对象文件扩展名是什么?

    当我在项目中构建java对象类时 将创建带有 class扩展名的构建文件 并且人类不可读 快速构建文件怎么样 example car java gt build gt car class 构建后会是什么 car swift gt build
  • 以编程方式触发iOS摇动事件

    如何以编程方式触发 iOS 中的摇动事件 我尝试过以下方法 但它总是崩溃 void shake NSLog TEST UIMotionEventProxy m NSClassFromString UIMotionEvent alloc in
  • iphone NSDate 转换问题

    在我的 facebook 图表 Api 中 我正在获取这些数据 来自杰森 updated time 2011 05 17T14 52 16 0000 我正在使用此代码将其转换为有效的日期格式 NSDateFormatter df NSDat
  • 使用 Android Firebase 堆栈推送通知

    我开发了使用 Firebase 接收推送通知的 Android 应用程序 我的代码基于 Firebase Google 官方文档 https firebase google com docs cloud messaging android
  • 我怎样才能勾勒出文本字体?

    我想在边框 轮廓 中显示另一种颜色的文本 我正在尝试使用在 MapOverlayView 中显示文本 text drawAtPoint CGPointMake 0 30 withFont UIFont fontWithName Helvet
  • UICollectionView 拖放文件夹创建

    我正在使用 UICollectionView 创建 iOS 画廊应用程序 我希望用户能够拖放图像来重新排序图库并创建文件夹 类似于 iPhone 上的主屏幕 我发现了以下内容tutorial http nshint io blog 2015
  • Google 地图 API -> OpenGLES 崩溃

    日志是从 Crashlytics 粘贴的 对于许多用户来说 崩溃经常发生 据我所知 它与设备 iOS 版本无关 我在我的代码中找不到任何错误 这似乎是纯粹的库问题 是 Google 地图 API 错误吗 我可以做些什么来修复它 或者我应该在
  • SKNode 上的 runAction 未完成

    我使用 NSOperation 子类来获取串行执行SKAction正如这个问题中所描述的 如何在 Swift 中子类化 NSOperation 以将 SKAction 对象排队以进行串行执行 https stackoverflow com
  • 在故事板中的视图控制器之间滑动手势

    我希望添加左右滑动手势来在视图控制器之间进行更改 这是否可能 并且有没有一种简单的方法可以在故事板中执行此操作 谢谢 故事板允许您在两个视图控制器之间设置 Segues 我想说首先在视图之间附加 Segues 给它一个标识符 然后使用类似的
  • 分发内部业务 IOS 应用程序

    我遇到了 IOS 应用程序分发的一个令人困惑的部分 因此 我需要简单细分一下我的限制 即仅将我的应用程序分发给我的员工 同事或任何被视为 内部 的人 这是表明我不希望该应用程序出现在应用程序商店中的另一种方式 我的情况是我为几家公司开发 他
  • 苹果推送通知在生产中不起作用

    我们完全陷入困境 请帮忙 我和我的团队制作了一个 iPhone 应用程序 这是我们第一次在 iOS 上尝试 一切都很好 直到我们提交应用程序并在应用程序商店上可用为止 推送通知服务无法正常工作 我在网上搜索并尝试根据人们的建议仔细检查我们的

随机推荐

  • 使用反射设置枚举

    如何使用反射设置枚举 我的班级有枚举 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 向他发送推送通知的权限 在此