关于个推的理解

来源:互联网 发布:教程网站源码 编辑:程序博客网 时间:2024/05/31 19:38

一、后台不能收到通知

首先要强调的一点是,假如程序退出前台之后不能收到通知是什么原因,刚开始的时候一直找一直找,问个推客服,都没解决,后面仔细看了有关APNS和个推的文档,根据个推文档的非本问题有关文档,我发现:




因为推送证书并不是我做的 所以我猜想是不是在苹果官网导出的推送证书不正确,所以我自己去根据个推的教程导了一遍,果然,成功了。可见,这些文档非常重要,要一步一步做。在此 仅附上少量截图与链接,不一一概述。






附录:创建Apple应用并创建APNS推送证书

注:上述只是其中几个截图,并不是连贯在一起的。

二、Clientid和devicetoken绑定

关于个推必须确认Clientid和devicetoken绑定是否正确”,绑定不正确,也有可能后台收不到通知,解决办法:1、可以先在手机上删除App,然后重新运行。2、找个推客服。当然第一点基于一定要 推送证书正确。

三、APNS推送的流程

看了很多关于苹果推送的文档,然后才对整个流程有个稍微清晰的理解。直接借用官方的图片,再加上自己的一些理解。




按照我的理解,是这样的。在3-3中,1、通过代码让手机先与苹果的APNS取得连接(苹果规定,推送服务必须由苹果APNS来对客户进行推送,所以,任何第三方都需先把推送发给苹果的APNS!!),2、从APNS获取本机的deviceToken(若是运用到第三方,例如:极光推送,百度云推送,个推。应该会由第三方来完成3-3),3、将本机的deviceToken与Client App(客户端应用程序)进行绑定,4、把deviceToken发给服务器(第三方)。

当需要服务器对App进行推送时,3-1,服务器会先发送信息给APNS,APNS再根据deviceToken发给对应的电脑或者手机端,再发至对应的App。

至此,整个推送的粗略流程完成。

四、使用定位功能

在使用个推中,由于个推的配置是在AppDelegate中完成,所以不可避免的代码终究要跳入我们的Controller。在使用定位的功能中,切记 加上代理要设为自己,猜想可能是因为:跳入Controller的时候 此时定位代理未设置 所以并不会执行定位代理。我做的时候 就半天没跳代理,弄的获取不了本机位置。贴上例子:
- (void)GexinSdkDidReceivePayload:(NSString *)payloadId fromApplication:(NSString *)appId{    // [4]: 收到个推消息        NSData *payload = [_gexinPusher retrivePayloadById:payloadId];    NSString *payloadMsg = nil;    if (payload) {        payloadMsg = [[NSString alloc] initWithBytes:payload.bytes                                              length:payload.length                                            encoding:NSUTF8StringEncoding];    }//    NSString *record = [NSString stringWithFormat:@"%d, %@, %@", ++_lastPayloadIndex, [NSDate date], payloadMsg];    NSString *record = [NSString stringWithFormat:@"%@",payloadMsg];    if (record != nil) {        ImmediLocaInfo *PositInfo = [[ImmediLocaInfo alloc] init];            if ([PositInfo.type isEqualToString:@"05"]) {                [_kqViewController lijidingwei:record];            }else if ([PositInfo.type isEqualToString:@"03"]){                [_kqViewController dingshidingwei:record];        }    }}
-(void)lijidingwei:(NSString *)aMsg{    //============立即定位===============//    _immediLocaInfo = [[ImmediLocaInfo alloc] init];    if (_userLocation == nil) {        _userLocation = [[BMKLocationService alloc] init];    }    _userLocation.delegate = self;    [ImmediLocaInfo sharedInstance].pType = 20;    NSLog(@"%@",_userLocation.delegate);    [_userLocation startUserLocationService];}

如代码所示 假如需要跳至不同的方法,然后在不同的方法里面又需跳至同一方法(例如本例中定位 都需跳入didUpdataUserLocation)。此时就需定个标志[ImmediLocaInfosharedInstance].pType = 20。必须用单例。因为跳入方法后 还需要继续跳回AppDelegate,此时若不设置单例,跳回去的时候,全局变量则会消失,不能判断

PS:记得遵守代理 百度地图定位代理为 BMKLocationServiceDelegate 。苹果自带定位代理为 CLLocationManagerDelegate ,CLLocationManager *locManager。

    locManager = [[CLLocationManager alloc]init];    //设置代理    locManager.delegate = self;    //设置位置经度    locManager.desiredAccuracy = kCLLocationAccuracyBest;    //设置距离过滤器为100米,表示每移动100米更新一次位置    locManager.distanceFilter = 100;    //开始定位服务    [locManager startUpdatingLocation];

//协议中的方法,作用是每当位置发生更新时会调用的委托方法- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{    //结构体,存储位置坐标    CLLocationCoordinate2D loc = [newLocation coordinate];    double longitude = loc.longitude;    double latitude = loc.latitude;    fx = [NSString stringWithFormat:@"%g",longitude];    fy = [NSString stringWithFormat:@"%g",latitude];    [locManager stopUpdatingLocation];}

五、个推代码理解

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{    NSLog(@"deviceToken: %@", deviceToken);    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];_deviceToken = [token stringByReplacingOccurrencesOfString:@" " withString:@""];    NSLog(@"deviceToken:%@", _deviceToken);            // [3]:向个推服务器注册deviceToken    if (_gexinPusher) {        [_gexinPusher registerDeviceToken:_deviceToken];    }}- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error{    // [3-EXT]:如果APNS注册失败,通知个推服务器    if (_gexinPusher) {        [_gexinPusher registerDeviceToken:@""];    }    NSLog(@"didFailToRegisterForRemoteNotificationsWithError:%@", [error localizedDescription]);}

#pragma mark - GexinSdkDelegate

- (void)GexinSdkDidRegisterClient:(NSString *)clientId

{

    [ImmediLocaInfosharedInstance].CID = clientId;

    // [4-EXT-1]: 个推SDK已注册

    _sdkStatus =SdkStatusStarted;

    //    [self stopSdk];

}

此时会收到 clientId ,[3]:向个推服务器注册deviceToken,成功绑定后 通知代理,返回 clientId 。

- (void)applicationDidEnterBackground:(UIApplication *)application{    // [EXT] 切后台关闭SDK,让SDK第一时间断线,让个推先用APN推送    [self stopSdk];}
一旦推出前台,让个推直接断线,然后服务器会发送推送消息给APNS,再由APNS来推送至手机端App。

- (void)applicationDidBecomeActive:(UIApplication *)application{    // [EXT] 重新上线    [self startSdkWith:_appID appKey:_appKey appSecret:_appSecret];}

后台收到通知后,点进程序,个推重新上线,开始执行代码。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userinfo{        // [4-EXT]:处理APN    [[UIApplication sharedApplication] cancelAllLocalNotifications];    [UIApplication sharedApplication].applicationIconBadgeNumber = 1;    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;    [self startSdkWith:_appID appKey:_appKey appSecret:_appSecret];    NSString *payloadMsg = [userinfo objectForKey:@"payload"];    NSString *record = [NSString stringWithFormat:@"[APN]%@, %@", [NSDate date], payloadMsg];}

此代码为不想通过个推的重新上线后来处理推送消息,而是通过APNS处理消息。


- (void)GexinSdkDidOccurError:(NSError *)error{    // [EXT]:个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。//    [_viewController logMsg:[NSString stringWithFormat:@">>>[GexinSdk error]:%@", [error localizedDescription]]];}



0 0
原创粉丝点击