ios推送信息实现

来源:互联网 发布:零存整取算法 编辑:程序博客网 时间:2024/04/28 01:47

 证书已经准备完毕,不懂请看我的前一篇文章http://blog.csdn.net/zhenli312/article/details/16844615

接下来,我们在xcode中新建一个测试工程,注意设置工程的Bundle Identifier必须与上面建的APP ID 里的相同

在didFinishLaunchingWithOptions 中加入一下代码

//注册接收通知类型
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:

     (UIRemoteNotificationType)(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken {

    NSLog(@"regisger success:%@", pToken);

    //注册成功,将deviceToken保存到应用服务器数据库中
    NSString *tokeStr = [NSString stringWithFormat:@"%@",pToken];

    if ([tokeStr length] == 0) {

        return;

    }

    NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"\<\>"];

    tokeStr = [tokeStr stringByTrimmingCharactersInSet:set];

    tokeStr = [tokeStr stringByReplacingOccurrencesOfString:@" " withString:@""];

    NSLog(@"令牌:%@", tokeStr);
    const char *s;

    s=[tokeStr UTF8String];

    GameRecord2::shared()->setdevice(s); //这里我把令牌传给一个类来处理,最后上传服务器
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    // 处理推送消息
    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"通知" message:[NSString stringWithFormat:@"\n%@",
                                                                        [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]] delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
    [alert show];
    [alert release];
    NSLog(@"%@", userInfo);
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Regist fail%@",error);  
}

到这里一切顺利的话我们就可以在真机运行了,注册成功我们会得到iphone 的deviceToken,

regisger success:<740f4707 bebcf74f 9b7c25d4 8e335894 5f6aa01d a5ddb387 462c7eaf 61bb78ad>

 

如果出现Code=3000 "未找到应用程序的“aps-environment”的权利字符串",说明你的证书错误,重新下个或者看看是否有push的服务。

 下面来看我的服务器php代码

<?php//@header("Content-Type: text/html; charset=gb2312");// 这里是我们上面得到的deviceToken,直接复制过来(记得去掉空格)$deviceToken = '484ccd7fe528cc7f1eda2482c161d219a62d14aa4785809d83569dac511c79be';// Put your private key's passphrase here:$passphrase = 'pushchat';// Put your alert message here:$message = 'weige';////////////////////////////////////////////////////////////////////////////////$ctx = stream_context_create();stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);// Open a connection to the APNS server//这个为正是的发布地址$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);//这个是沙盒测试地址,发布到appstore后记得修改哦//$fp = stream_socket_client(//'ssl://gateway.sandbox.push.apple.com:2195', $err,//$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);if (!$fp)exit("Failed to connect: $err $errstr" . PHP_EOL);echo 'Connected to APNS' . PHP_EOL;// Create the payload body$body['aps'] = array('alert' => $message,'badge' => 1,    'sound' => 'default');// Encode the payload as JSON$payload = json_encode($body);// Build the binary notification$msg = chr(0).pack('n', 32).pack('H*', $deviceToken).pack('n', strlen($payload)).$payload;echo $payload ."\n";// Send it to the server$result = fwrite($fp, $msg, strlen($msg));if (!$result)echo 'Message not delivered' . PHP_EOL;elseecho 'Message successfully delivered' . PHP_EOL;// Close the connection to the serverfclose($fp);?>

之前生成的ck.pem要与该php放在同目录下,上面的开发地址用来开发证书用的,作为测试。如果改为发布证书后需要改为发布地址。

deviceToken是设备口令,message是向用户发送的信息,这些都可以配置,我在这里写死了为了测试。

 

另外,当你的iPhone收到推送信息后到底会发生什么呢?总共有三种可能性:

  • app在前台运行. 接收到推送信息时屏幕上不会有任何显示,也不会有提示音,但你的app delegate会收到这个推送信息。你可以在这里加入代码来处理接收到的信息。
  • app不在前台运行。iPhone可能停留在主界面或者另一个app正在运行.一个提示窗口会弹出,可能伴随着提示音。用户可以点击Close按钮来关闭这个窗口或者点击View按钮来打开你的app。如果用户点击的时Close按钮,那你的app不会处理这个推送的信息。
  • iPhone在锁屏状态下. 同样一个提示窗口弹出,并伴随着提示音,但是这个窗口不会有Close和View按钮。屏幕解锁后会自动进入你的app。

因为app delegate是接收推送信息的地方,我们对app的最后改动都是在AppDelegate.m文件中。我们需要修改两处:

  1. application:didFinishLaunchingWithOptions:函数. 如果推送信息到达时你的app不在前台运行,而用户在弹出窗口点击了“View”按钮,你的app会重新运行然后这个信息会作为参数注入到application:didFinishLaunchingWithOptions:函数中。
  2. application:didReceiveRemoteNotification:函数. 如果信息到达时你的app正在前台运行,那这个函数就会被调用。在iOS4.0或更新的版本,如果你的app从暂停状态进入前台,这个函数也会被调用。你可以用UIApplication的applicationState属性来检查你的app是否是从暂停状态苏醒。

我上面一开始就写了didReceiveRemoteNotification方法里的响应,现在开始对1处理,

在didFinishLaunchingWithOptions加入:

if (launchOptions !=nil) {
        NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (dictionary !=nil) {
            [self addMessageFormRemoteNotification:dictionary updateUI:NO];
        }

    }

 

同时写上

- (void)addMessageFormRemoteNotification:(NSDictionary*)userInfo updateUI:(BOOL)updateUI
{
    // 处理推送消息
    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"通知" message:[NSString stringWithFormat:@"\n%@",
                                                                        [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
    [alert show];
    [alert release];
    NSLog(@"%@", userInfo);
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];  
}

处理信息中的[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]是为了让信息变为0

 

ok,这样就可以完美实现了!


2013-12-10-----------

消除通知,发现setApplicationIconBadgeNumber为0,没有效果

我就加上UIApplication sharedApplication] cancelAllLocalNotifications   就OK了