关于个推的理解

一、后台不能收到通知

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




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

关于个推的理解_第1张图片

关于个推的理解_第2张图片

关于个推的理解_第3张图片

关于个推的理解_第4张图片


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

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

二、Clientid和devicetoken绑定

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

三、APNS推送的流程

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


关于个推的理解_第5张图片


按照我的理解,是这样的。在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)。 此时就需定个标志[ ImmediLocaInfo sharedInstance ]. 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]]];
}



你可能感兴趣的:(推送)