3

我有这样的情况,我正在登录应用程序,然后我将设备令牌发送到服务器并收到推送通知。如果消费者从应用程序中注销,那么我正在向服务器发送请求,那么我不会收到推送通知。如果用户在登录后卸载应用程序,那么我无法向服务器发送停止推送通知的请求,然后我再次安装应用程序但我没有登录,然后我会自动收到推送通知。

所以我的问题是当用户没有登录应用程序时如何停止推送通知

4

3 回答 3

2

有点晚了,但它可能会帮助某人。

我在我的一个项目中遇到了类似的情况:

问题

  1. 第一次运行获取设备令牌
  2. 用户登录,应用程序向服务器注册设备令牌
  3. 用户在未注销的情况下卸载应用程序,因此服务器仍然认为它处于活动状态
  4. 用户重新安装应用程序,即使他们尚未登录,仍会收到推送通知

在我的应用程序中,我在应用程序委托中注册并请求设备令牌:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
       ..
       [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
       (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
       ..
}

一旦收到 Apple 的回复:

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)token{
        //Get trimmed device token
        NSString *deviceToken = [[token description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
        deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];

        //Store the device token in the user defaults
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        [userDefaults setObject:deviceToken forKey:@"dToken"];
        [userDefaults synchronize];
 }

这或多或少是我见过的典型方式。

现在当用户登录时,设备令牌被发送到服务器并从用户内容区域的主视图控制器注册。通过从该视图控制器中访问用户默认值来检索设备令牌。然而问题是,如果用户从未登录到用户内容区域,通知将仍然存在,因为设备从未在服务器上注销,因为之前的卸载导致仍然登录。

解决方案

如其他答案中所述,有几种方法可以解决此问题。但是我不想修改我的服务器和在那里注册设备的主要结构,类似于:

  • 用户首次登录时:同时对用户进行身份验证和注册传递的设备令牌。
  • 当用户注销时:取消向该用户注册设备令牌。
  • 每当数据库中存在设备令牌时:为除当前登录的用户之外的所有用户停用它。

看到用户内容区域必须有设备令牌才能登录用户,我开始像之前一样在didFinishLaunchingWithOptions中请求设备令牌。

现在,当在didRegisterForRemoteNotificationsWithDeviceToken中收到回复时,我执行以下操作:

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)token{
        //Get trimmed device token
        NSString *deviceToken = [[token description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
        deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];

        //Store the device token in the user defaults
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        [userDefaults setObject:deviceToken forKey:@"dToken"];
        [userDefaults synchronize];

        //If not logged in yet, unregister for notifications
        if(![[NSUserDefaults standardUserDefaults] objectForKey:@"loggedIn"])
            [[UIApplication sharedApplication] unregisterForRemoteNotifications];
 }

我检查是否尚未到达用户内容视图控制器,即用户从未登录,并禁用通知。

在用户内容视图控制器中,我执行以下操作:

- (void)viewDidLoad{
    ..
    //Set logged-in so the notifications continue to be received
    if(![[NSUserDefaults standardUserDefaults] objectForKey:@"loggedIn"]){
        [[NSUserDefaults standardUserDefaults] setValue:@"done" forKey:@"loggedIn"];
        [[NSUserDefaults standardUserDefaults] synchronize];

        //Register for notifications (again)
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    }

    //Send user authentication and device token (retrieved from the user defaults) to server
    ..
}

现在,每当用户第一次登录时,设备令牌就会立即发送到服务器并注册,因为它已经从 Apple 检索到了。在用户登录之前,通知也被禁用,因此主要问题得到解决。

这种方法确保用户内容区域视图控制器在没有保存在用户默认值中的设备令牌的情况下永远不会加载,因此允许我继续使用相同的方法来验证用户并立即传递设备令牌。

于 2013-10-23T18:57:13.567 回答
1

您可以通过在您的设备上本地存储一些数据(例如,您可以存储设备令牌)来识别应用程序首次启动的时间(在第一次安装之后或卸载并重新安装之后)。

首次启动应用程序时,将设备令牌发送到您的服务器的请求中,该请求将清除任何引用该设备令牌的数据库条目(与用户注销时发送到服务器的请求相同)。这样,在用户登录之前,您的服务器不会向此设备令牌发送推送通知。

下次用户登录应用程序时,将设备令牌和用户 ID 在请求中发送到您的服务器,以开始使用该设备令牌为该用户发送推送通知。

于 2013-08-16T14:13:57.170 回答
0

我喜欢这种情况...检查我的逻辑。

您拥有的第一个重要的事情是,当应用程序卸载时,它的数据库也会消失。这就是诀窍。

==>您必须维护一个从 1 开始的参考编号。(您可以将其硬编码并且只需更新)每次使用此参考编号与您的

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//get value from database,increment  by 1
//sync with server
}

每次应用程序启动时,您还必须增加参考编号。还需要在服务器端跟踪此参考号。

第二种情况(即您面临的问题)是重新安装应用程序时:所有数据库都会自动消失。==>这是诀窍

当您下次使用数据库中的参考号时,它将是 1。

现在将其与服务器端进行比较。

在重新安装应用程序后的第二种情况之后,您的参考号将小于当前维护的参考号,即(1< 当前维护的参考号@server)这是知道服务器重新安装应用程序并需要等到身份验证的条件。

所以让服务器禁止当前设备的通知,直到用户登录。成功登录后更新所有数据库并允许服务器发送通知。

于 2013-08-16T11:19:03.300 回答