ios推送通知_ios11 开启推送通知权限 - CSDN
精华内容
参与话题
  • ios如何实现推送通知

    万次阅读 2012-04-05 14:34:54
    推送通知的步骤:1、询问是否允许推送通知。2、如果用户允许在APPDELEGATE 中实现 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ ...
    推送通知的步骤:1、询问是否允许推送通知。2、如果用户允许在APPDELEGATE 中实现
    

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

    }

    3、将token发送到服务器上

    4、服务器收到toke后 发送推送通知,客户端相应该推送同通知


    代码如下:

    //每次唤醒
    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
        /*
         Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
         */
        
        //每次醒来都需要去判断是否得到device token
        [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(registerForRemoteNotificationToGetToken) userInfo:nil repeats:NO];
        //hide the badge
        application.applicationIconBadgeNumber = 0;
    
        [[CheckVersion sharedCVInstance] checkVersionOfServer];
        
        [[AnalyticsUtil sharedAnalyticsUtil] appLaunch];
        
        AnalyticsJSONElement *viewElement = [[AnalyticsJSONElement alloc] init];
        viewElement.jsonType = AnalyticsJSONTypeView;
        viewElement.typeID = @"0";
        [[AnalyticsUtil sharedAnalyticsUtil] postAnalyticsMsgToServerWithElement:viewElement];
        [viewElement release];
    
        
    }
    
    - (void)applicationWillTerminate:(UIApplication *)application
    {
        /*
         Called when the application is about to terminate.
         Save data if appropriate.
         See also applicationDidEnterBackground:.
         */
    }
    
    
    #pragma mark -
    #pragma mark - Getting Device token for Notification support
    //向服务器申请发送token 判断事前有没有发送过
    - (void)registerForRemoteNotificationToGetToken
    {
        NSLog(@"Registering for push notifications...");
        
        //注册Device Token, 需要注册remote notification
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    	
        
        if (![userDefaults boolForKey:DeviceTokenRegisteredKEY])   //如果没有注册到令牌 则重新发送注册请求
    	{
    		dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                
                [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
                 (UIRemoteNotificationTypeNewsstandContentAvailability | 
                  UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
                  UIRemoteNotificationTypeSound)];
    		});
    	}
        
        //将远程通知的数量置零
        dispatch_async(dispatch_get_global_queue(0,0), ^{
            //1 hide the local badge
            if ([[UIApplication sharedApplication] applicationIconBadgeNumber] == 0) {
                return;
            }
            // [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
            
            //2 ask the provider to set the BadgeNumber to zero
    		NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    		NSString *deviceTokenStr = [userDefaults objectForKey:DeviceTokenStringKEY];
    		[self resetBadgeNumberOnProviderWithDeviceToken:deviceTokenStr];
    	});
        
    }
    
    //允许的话 自动回调的函数
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        
    	//将device token转换为字符串
    	NSString *deviceTokenStr = [NSString stringWithFormat:@"%@",deviceToken];
        
        
        //modify the token, remove the  "<, >"
    	NSLog(@"    deviceTokenStr  lentgh:  %d  ->%@", [deviceTokenStr length], [[deviceTokenStr substringWithRange:NSMakeRange(0, 72)] substringWithRange:NSMakeRange(1, 71)]);
    	deviceTokenStr = [[deviceTokenStr substringWithRange:NSMakeRange(0, 72)] substringWithRange:NSMakeRange(1, 71)];
        
        NSLog(@"deviceTokenStr = %@",deviceTokenStr);
    	
        
        //将deviceToken保存在NSUserDefaults
        
        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        //保存 device token 令牌,并且去掉空格
    	[userDefaults setObject:[deviceTokenStr stringByReplacingOccurrencesOfString:@" " withString:@""] forKey:DeviceTokenStringKEY];      
    	
        
        
    	
        //send deviceToken to the service provider
        
        dispatch_async(dispatch_get_global_queue(0,0), ^{
            
            //没有在service provider注册Device Token, 需要发送令牌到服务器
            if ( ![userDefaults boolForKey:DeviceTokenRegisteredKEY] )
            {
                NSLog(@" 没有 注册Device Token");
                [self sendProviderDeviceToken:deviceTokenStr];
            }
        });
        
        
    }
    
    - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
        
        NSString *str = [NSString stringWithFormat: @"Error: %@", err];
        NSLog(@"获取令牌失败:  %@",str);
        
        //如果device token获取失败则需要重新获取一次
        //[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(registerForRemoteNotificationToGetToken) userInfo:nil repeats:NO];
    }
    
    
    
    //获取远程通知
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    	
    	NSLog(@"received badge number ---%@ ----",[[userInfo objectForKey:@"aps"] objectForKey:@"badge"]);
        
        for (id key in userInfo) {
            NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
        }    
    	
        NSLog(@"the badge number is  %d",  [[UIApplication sharedApplication] applicationIconBadgeNumber]);
        NSLog(@"the application  badge number is  %d",  application.applicationIconBadgeNumber);
        application.applicationIconBadgeNumber += 1;
        
    
        // We can determine whether an application is launched as a result of the user tapping the action
        // button or whether the notification was delivered to the already-running application by examining
        // the application state.
    	
        //当用户打开程序时候收到远程通知后执行
    	if (application.applicationState == UIApplicationStateActive) {
            // Nothing to do if applicationState is Inactive, the iOS already displayed an alert view.
    		UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"温馨提示"
    															message:[NSString stringWithFormat:@"\n%@",
    																	 [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]
    														   delegate:self
    												  cancelButtonTitle:@"OK"
    												  otherButtonTitles:nil];
            
            dispatch_async(dispatch_get_global_queue(0,0), ^{
                //hide the badge
                application.applicationIconBadgeNumber = 0;
                
                //ask the provider to set the BadgeNumber to zero
                NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
                NSString *deviceTokenStr = [userDefaults objectForKey:DeviceTokenStringKEY];
                [self resetBadgeNumberOnProviderWithDeviceToken:deviceTokenStr];
            });
            
    		[alertView show];
    		[alertView release];
            
    	}
        
        
    }
    
    
    
    // http://192.168.11.24/ClientInterface.ashx?action= savetoken&clientid=3898329492492424924932&token=343424324242
    
    #pragma mark -
    #pragma mark - Getting Device token for Notification support
    
    
    //发送token
    - (void)sendProviderDeviceToken: (NSString *)deviceTokenString
    {
    
        // Establish the request
    	NSLog(@"sendProviderDeviceToken = %@", deviceTokenString);
        
        NSString *UDIDString = [[UIDevice currentDevice] uniqueIdentifier];
    	NSString *body = [NSString stringWithFormat:@"action=savetoken&clientid=%@&token=%@", UDIDString, deviceTokenString];
        
        NSString *baseurl = [NSString stringWithFormat:@"%@?",URL_OF_PUSH_NOTIFICATION_SERVER];  //服务器地址
        
        NSLog(@"send provider device token = %@", baseurl);
        
    	NSURL *url = [NSURL URLWithString:baseurl];
    	NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
        
    	[urlRequest setHTTPMethod: @"POST"];
    	[urlRequest setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
    	[urlRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        
    	NSURLConnection *tConnection = [[NSURLConnection alloc] initWithRequest: urlRequest delegate: self];
    	self.deviceTokenConnetion = [tConnection retain];
    	[tConnection release];
    }
    
    #pragma mark -
    #pragma mark - reset Badge Number
    
    - (void)resetBadgeNumberOnProviderWithDeviceToken: (NSString *)deviceTokenString
    {
    	NSLog(@"  reset Provider DeviceToken %@", deviceTokenString);
    	isNotificationSetBadge = YES;
    	
        // Establish the request
    	NSString *body = [NSString stringWithFormat:@"action=setbadge&token=%@", [deviceTokenString stringByReplacingOccurrencesOfString:@" " withString:@""]];
        
    	NSString *baseurl = [NSString stringWithFormat:@"%@?", URL_OF_PUSH_NOTIFICATION_SERVER];  //服务器地址
    	NSURL *url = [NSURL URLWithString:baseurl];
    	NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
    	
    	[urlRequest setHTTPMethod: @"POST"];
    	[urlRequest setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
    	[urlRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    	
    	NSURLConnection *tConnection = [[NSURLConnection alloc] initWithRequest: urlRequest delegate: self];
    	self.deviceTokenConnetion = [tConnection retain];
    	[tConnection release];
    }
    
    #pragma mark -
    #pragma mark - NSURLConnection delegate function
    
    
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
    	NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
    	NSLog(@"Response statusCode:    %d", resp.statusCode);
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
    	NSString *rsp = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    	NSLog(@"connection    2  Received data = %@  ", rsp);
        
        
        
        //if the string from provider is "true", means the devicetoken is stored in the provider server
        //so the app won't send the devicetoken next time.
    	if (isNotificationSetBadge == NO) {
            
    		NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    		if([rsp isEqualToString:@"true"])
    		{
                NSLog(@"connection    2.2  Received data = %@  ", rsp);
    			[userDefaults setBool:YES forKey:DeviceTokenRegisteredKEY]; 	
    		}
            
    	}else{//isNotificationSetBadge == YES;
    		NSLog(@"connection    2  reset");
    		isNotificationSetBadge = NO;
    	}
    	
    	[rsp release];
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
    	NSLog(@"connection    3  Did Finish Loading ");
    	[self.deviceTokenConnetion cancel];
    }	
    

    展开全文
  • IOS开发之实现App消息推送(最新)

    万次阅读 多人点赞 2016-06-20 14:45:52
    今天就由本菜鸟给大家做一个简单的IOSApp消息推送教程吧!一切从0开始,包括XCode6, IOS8, 以及苹果开发者中心最新如何注册应用,申请证书以及下载配置概要文件,相信很多刚开始接触ios的人会很想了解一下。(ps:...

    好久没有写过博客啦,今天就由本菜鸟给大家做一个简单的IOSApp消息推送教程吧!一切从0开始,包括XCode6, IOS8, 以及苹果开发者中心最新如何注册应用,申请证书以及下载配置概要文件,相信很多刚开始接触ios的人会很想了解一下。(ps:网上看了一下虽然有很多讲述推送的好教程,我也是看着一步步学会的,但是这些教程的时间都是去年或者更早时期的,对引导新手来说不是很合适

    第一部分

    首先第一步当然是介绍一下苹果的推送机制(APNS)咯(ps:其实每一篇教程都有),先来看一张苹果官方对其推送做出解释的概要图。

    Provider是给你手机应用发出推送消息的服务器,而APNS(Apple Push Notification Service)则是苹果消息推送服务器。你本地的服务器当需要给应用推送一条消息的时候,先要将消息发出到苹果推送服务器,然后再由苹果推送服务器将消息发到安装了该应用的手机。

    接下来再看一张解释图:


    根据上图的逻辑我来给大家解释一下:

    1.你的IOS应用需要去注册APNS消息推送功能。

    2.当苹果APNS推送服收到来自你应用的注册消息就会返回一串device token给你(很重要)

    3.将应用收到的device Token传给你本地的Push服务器。

    4.当你需要为应用推送消息的时候,你本地的推送服务器会将消息,以及Device Token打包发送到苹果的APNS服

    5.APNS再将消息推送给目的iphone


    第二部分

    1.从证书颁发机构颁发证书

    打开你mac的钥匙串访问: 然后点击钥匙串访问


    随后它会弹出一个窗口用户电子邮件信息就填写你苹果开发者账号的名称即可(应该是一个邮件名称),点击保存到磁盘的选

    项,点击继续,显示如下:



    点击存储,文件名为:CertificateSigningRequest.certSigningRequest 随后将他放在一个文件夹中我们取名push吧!


    第三部分

    访问苹果开发者网址:https://developer.apple.com/


    选中MemberCenter选项,进入登陆页面,用你的苹果开发者账号登陆,过一会网页就会自动跳转到下图。

    点击红色所选部分内容进行下一步的操作。


    选择Certificates选项,设置证书,如图所示先解释一下:

     


    Development选项的作用顾名思义就是用来作为开发使用的证书,Production选项则是用来发布产品使用的,名称很陌生是不是,之

    前的开发者网页是没有这一选项的,可能是苹果把他修改了,用这个名称更加能让人理解吧(字面上解释就是产品么)。两个选项生

    成证书的步骤是一样的,现在我们使用开发者的选项进行证书的制作,步骤如下:选择Development选项:



    点击上面的加号选项,



    选择APNS选项(开发么当然是在沙盒环境下了,模拟真实情况),然后Continue



    这个AppID我们在下一部分讲如何生成,现在我用的是已经生成好的一个应用ID,继续Continue



    这边就要选择在钥匙串访问环节下载下来的CertificateSigningRequest.certSigningRequest文件了,选择并生成:


    点击下载,得到aps_development .cer,保存到push文件中去。


    第四部分

    新建一个AppID,选择网页上的AppIDs,然后点击右上角的 “加号



    App的取名只要按照苹果要求的就可以了



    然后BundleID是比较重要的,在提交审核以及测试(苹果的TestFlight)和付费环节都需要用到,也只需按照苹果要求来写就好了。



    接下来就是对你的应用需要使用苹果的哪些服务进行选择就行了,例如广告,游戏中心,推送,付费等等情况。


    最后选择“Submit”选项,在下一个界面中选择“done”选项,这样我们设置AppID的步骤我们就完成了。


    第五部分:生成Provisioning Profiles

    这个配置概要文件分为两种,一种是为开发使用的,还有一种则是为发布到appStore上面。


    创建发布版的ProvisioningProfile与开发版的流程相同,点击Development然后点击右上角的加号


    会进入选择何种配置概要文件的界面:



    我们现在时测试,所以选择“IOS App Development”的选项,在下面的Distribution发布选项中有两个选择,“App Store”以及

    “Ad hoc”,你可以根据下面的描述选择你发布所需的选项。点击Continue进入下一步。


    选择你上一步创建的AppID,点击Continue 进行下一步


    选择你的开发者账号,Continue进行下一步


    在这一步上选择你的设备(你只有在这一步上勾选了你的设备,你才能在设备上用这个签名进行调试)。关于如何将你的设备号添加

    进去也是非常简单的,选择左侧的"Devices",然后点击右上角的加号,在随后出来的页面上添加你设备的UUID(在XCode中可以查

    看到)以及name( 可以随便取,自己看的懂就行)然后Register一下,照着流程走到最后一步就完成了。

    好咱们继续回到上面的Provisioning Profile配置环节,当你选好了你的设备后点击“Continue”进入下一页,



    输入一个文件名(最好是起的能看懂是干嘛的,当然也可以随便起),点击“Generate”进入下一个页面,在这个页面中就会有一个下

    载按钮让你下载这个文件,我们把它下载下来放在Push文件夹中。


    第六部分

    好了,前期的准备工作都已经做完了,现在让我们开始推送吧!(吼吼)

    首先双击我们生成的 “aps_development .cer” 文件,进入钥匙串访问,找到我们的专用秘钥(根据在第二部分中从证书机构颁发证书操作中填写的常用名



    我在第二部分填写的是“silicon”,由于换了一台mac之前安装的没有了,之前没有截图,所以随便找了个图给大家看一下,凭大家的聪明才智应该不难理解吧。

    然后右击导出,会弹出如下所示的图。



    将他存储到push文件夹中,命名为“push.p12”,在这一步中导出会让你输入密码并验证,你可以自定义一个密码,例如abc123

    现在push文件夹中应该有几个文件“aps_development .cer” ,"push.p12",“CertificateSigningRequest.certSigningRequest”以及

    刚才下下来的配置概要文件。


    接下来我们打开终端将他们生成.pem文件

    1.把aps_development .cer文件生成.pcm文件,cd到push文件夹下



    2.把push.p12文件生成为.pem文件


    上边输入的密码则是你导出证书所设的密码,即abc123.接着还会让你输入.pem文件的密码,还是使用abc123好了,防止混淆。

    这样我们在push文件夹中就又得到了两个文件,PushChatCert.pem和PushChatKey.pem。


    3.把PushChatCert.pem和PushChatKey.pem合并为一个pem文件,



    在push文件夹中又多了一个ck.pem文件,以上我们把需要使用的文件都准备好了


    接下来就要测试一下啦,是不是很激动~

    为了测试证书工作的状况,我们可以使用“telnet gateway.sandbox.push.apple.com 2195”来检测一下,如果显示下图则表示成功了。



    然后,我们使用我们生成的证书和私钥来设置一个安全的链接去链接苹果服务器

    在终端输入如下命令:openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem

    需要输入密码(abc123 我们刚才所设置的)。

    然后他会返回一系列的数据,这里我就粘贴一部分啦:


    CONNECTED(00000003)

    depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C

    verify error:num=20:unable to get local issuer certificate

    verify return:0

    ---

    Certificate chain

    。。。。。(省略)

    。。。。。(省略)

    。。。。。(省略)

        Start Time: 1416389389

        Timeout   : 300 (sec)

        Verify return code: 0 (ok)

    ---

    测试就到这里啦。。。


    第七部分

    1.建立推送项目

    //
    //  AppDelegate.m
    //  TestPushNotifiy
    //
    //  Created by silicon on 14-10-30.
    //  Copyright (c) 2014年 silicon. All rights reserved.
    //
    
    #import "AppDelegate.h"
    
    @implementation AppDelegate
    @synthesize mainView = _mainView;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
        {
            //IOS8
            //创建UIUserNotificationSettings,并设置消息的显示类类型
            UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:nil];
            
            [application registerUserNotificationSettings:notiSettings];
            
        } else{ // ios7
            [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge										 |UIRemoteNotificationTypeSound										 |UIRemoteNotificationTypeAlert)];
        }
        
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
        
        self.mainView = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
        self.window.rootViewController = self.mainView;
        return YES;
    }
    
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken{
        NSLog(@"---Token--%@", pToken);
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
        
        NSLog(@"userInfo == %@",userInfo);
        NSString *message = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"];
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        
        [alert show];
    }
    
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    
        NSLog(@"Regist fail%@",error);
    }
    
    - (void)applicationWillResignActive:(UIApplication *)application
    {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }
    
    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }
    
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }
    
    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }
    
    - (void)applicationWillTerminate:(UIApplication *)application
    {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
    
    @end
    

    在appdelegate.m中加入以上代码,

    if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
        {
            //IOS8
            //创建UIUserNotificationSettings,并设置消息的显示类类型
            UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:nil];
            
            [application registerUserNotificationSettings:notiSettings];
            
        } else{ // ios7
            [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge										 |UIRemoteNotificationTypeSound										 |UIRemoteNotificationTypeAlert)];
        }

    由于ios8的推送跟ios7及以下的不一样,所以需要加判断来注册消息推送。

    函数:

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken{
        NSLog(@"---Token--%@", pToken);
    }


    会接收来自苹果服务器给你返回的deviceToken,然后你需要将它添加到你本地的推送服务器上。(很重要,决定你的设备能不能接收到推送消息)。

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
        
        NSLog(@"userInfo == %@",userInfo);
        NSString *message = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"];
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        
        [alert show];
    }

    这个函数则是当设备接收到来自苹果推送服务器的消息时触发的,用来显示推送消息。

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

    当注册失败时,触发此函数。



    2.PHP服务端

    将simplepush.php这个推送脚本也放在push文件夹中

    <?php
    
    // ??????????deviceToken???????????????
    $deviceToken = 'c95f661371b085e2517b4c12cc76293522775e5fd9bb1dea17dd80fe85583b41';
    
    // Put your private key's passphrase here:
    $passphrase = 'abc123';
    
    // Put your alert message here:
    $message = 'My first push test!';
    
    
    
    $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,
    '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;
    
    // Send it to the server
    $result = fwrite($fp, $msg, strlen($msg));
    
    if (!$result)
    echo 'Message not delivered' . PHP_EOL;
    else
    echo 'Message successfully delivered' . PHP_EOL;
    
    // Close the connection to the server
    fclose($fp);
    ?>

    deviceToken填写你接收到的token,passPhrase则填写你的ck.pem设置的密码。

    此刻就是见证奇迹的时候了,使用终端进入到push文件夹,在终端输入 php simplepush.php



    若显示以上提示则表示推送成功了。附上一张成功图。



    推送就到这边吧!

    感谢这篇博客的指导:http://blog.csdn.net/showhilllee/article/details/8631734


    simplepush.php以及XCode工程我会上传到我的资源里去,大家可以去那边下载。有什么不明白的地方大家可以留言或者私信我,我会第一之间回复的~



    大家可以关注我的微信公众号与我互动,相关问题也可以直接用公众号联系我:












    展开全文
  • iOS12中推送通知新特性

    千次阅读 2019-07-05 10:16:07
    点击上方“iOS开发”,选择“置顶公众号”关键时刻,第一时间送达!序言众所周知,iOS中消息推送扮演了不可或缺的位置。不管是本地通知还是远程通知无时不刻的在影响着我们的用...
        

    点击上方“iOS开发”,选择“置顶公众号”

    关键时刻,第一时间送达!

    640?640?wx_fmt=gif


    序言

    众所周知,iOS中消息推送扮演了不可或缺的位置。不管是本地通知还是远程通知无时不刻的在影响着我们的用户体验,以致于在iOS10的时候苹果对推送大规模重构,独立了已UserNotifications和UserNotificationsUI两个单独的framework,可见重要性一斑。针对于WWDC18苹果又给我们带来了什么惊喜呢?


    新特性

    • Grouped notifications 推送分组

    • Notification content extensions 推送内容扩展中的可交互和动态更改Action

    • Notification management 推送消息的管理

    • Provisional authorization 临时授权

    • Critical alerts 警告性质的推送


    推送分组

    随着手机上应用的增多,尤其QQ和微信这两大聊天工具,当手机锁屏的时候,伴随着就是好满屏的推送消息。这一现象不知大家有没有觉着不高效和体验性比较差呢?苹果针对锁屏情况下,对消息进行了分组,从而有效的提高了用户的交互体验,分组形式如下:


    640?wx_fmt=other


    分组形式:

    • 苹果会自动帮我们以APP的为分类依据进行消息的分组;

    • 如果我们设置了threadIdentifier属性则以此属性为依据,进行分组。


    640?wx_fmt=other

    代码如下:

    let content = UNMutableNotificationContent() 
    content.title = "Notifications Team" 
    content.body = "WWDC session after party" 
    content.threadIdentifier = "notifications-team-chat"//通过这


    摘要(Summary)格式定制

    当苹果自动将推送消息的归拢到一起的时候,最下边会有一个消息摘要。默认格式是:n more notifications from xxx。不过此格式我们是可以定制的。


    • 第一种

    let summaryFormat = "%u 更多消息啦啦"
    return UNNotificationCategory(identifier: "category-identifier",
    actions: [],
    intentIdentifiers: [],
    hiddenPreviewsBodyPlaceholder: nil,
    categorySummaryFormat: summaryFormat,
    options: [])


    640?wx_fmt=jpeg


    • 第二种

    let summaryFormat = “%u 更多消息啦啦!来自OceanFish”
    let content = UNMutableNotificationContent()
    content.body = "..."
    content.summaryArgument = "OceanFish"


    640?wx_fmt=jpeg


    同一个category的不同格式,苹果会将其合并在一起;并且不同的summaryArgument苹果也会将其默认合并到一起进行显示


    640?wx_fmt=jpeg


    也可以通过let summaryFormat = NSString.localizedUserNotificationString(forKey: "NOTIFICATION_SUMMARY", arguments: nil)来进行本地化服务


    数字定制


    有时会出现另一个场景:比如发送了2条推送消息,一条是“你有3个邀请函”,另一条是“你有5个邀请函”。那摘要则会显示你有2更多消息。这显然不是我们想要的!我们最好的期望肯定是"你有8个邀请函"。那这种效果怎么显示呢?


    苹果给我们提供了另外一个属性,结合上边的摘要(Summary)格式定制我们可以实现以上效果。


    let content = UNMutableNotificationContent()
    content.body = "..."
    content.threadIdentifier = "..."
    content.summaryArgument = "Song by Song"
    content.summaryArgumentCount = 3


    当多个消息归拢到一起的时候,苹果会将summaryArgumentCount值加在一起,然后进行显示


    推送内容扩展中的可交互和动态更改Action


    之前消息是不支持交互的和动态更改Action的,比如界面有个空心喜欢按钮,用户点击则变成了实心喜欢按钮;有个Acction显示“喜欢”,用户点击之后变成"不喜欢"


    推送界面可交互


    640?wx_fmt=jpeg


    如上图推送界面有个空心喜欢按钮


    • 首先配置Notification Content Extention的UUNNotificationExtensionUserInteractionEnabled为YES


    640?wx_fmt=jpeg


    然后代码实现


    import UserNotificationsUI
    class NotificationViewControllerUIViewControllerUNNotificationContentExtension {

        @IBOutlet var likeButton: UIButton?

        likeButton?.addTarget(self, action: #selector(likeButtonTapped), for: .touchUpInside)

        @objc func likeButtonTapped() {
            likeButton?.setTitle("♥"for: .normal)
            likedPhoto()
        }
    }


    Action动态化


    640?wx_fmt=jpeg


    640?wx_fmt=jpeg


    // Notification Content Extensions
    class NotificationViewControllerUIViewControllerUNNotificationContentExtension {

        func didReceive(_ response: UNNotificationResponse, completionHandler completion:
            (UNNotificationContentExtensionResponseOption
    ) -> Void) 
    {
            if response.actionIdentifier == "like-action" {
                // Update state...
                let unlikeAction = UNNotificationAction(identifier: "unlike-action",
                                                        title: "Unlike", options: [])
                let currentActions = extensionContext?.notificationActions
                let commentAction = currentActions![1]
                let newActions = [ unlikeAction, commentAction ]
                extensionContext?.notificationActions = newActions
            }
        }
    }


    performNotificationDefaultAction()用于点击推送的时候启动应用;dismissNotificationContentExtension()用于关闭锁屏页面的推送具体一条消息


    推送消息的管理


    这个主要是苹果针对消息增加了一个“管理”的按钮,消息左滑即可出现。

    640?wx_fmt=jpeg

    帮助我们快速的针对消息进行设置。

    • Deliver Quietly 则会不会播放声音。

    • turn off 则会关闭推送

    • Setttings 我们可以自己定制


    import UIKit
    import UserNotifications
    class AppDelegateUIApplicationDelegateUNUserNotificationCenterDelegate {
        func userNotificationCenter(_ center: UNUserNotificationCenter,
                                    openSettingsFor notification: UNNotification? ) {

        }
    }


    临时授权


    临时授权主要体现就是推送消息过来会有两个按钮,会主动让用户自己选择

    640?wx_fmt=jpeg

    let notificationCenter = UNUserNotificationCenter.current()

    noficationCenter.requestAuthorization(options: [.badge,.alert,.sound,.provisional]) { (tag, error) in

    }


    在申请权限的时候,加上provisional即可。


    警告消息


    比如家庭安全、健康、公共安全等因素的时候。此消息需要用户必须采取行动。最简单的一个场景是家里安装了一个摄像头,我们去上班了,此时如果家中有人,则摄像头会推送消息给我们。

    640?wx_fmt=jpeg


    • 证书申请

    https://developer.apple.com/contact/request/notifications-critical-alerts-entitlement/

    • 本地权限申请

    let notificationCenter = UNUserNotificationCenter.current()
    noficationCenter.requestAuthorization(options: [.badge,.alert,.sound,.criticalAlert]) { (tag, error) in

    }


    在申请权限的时候,加上criticalAlert。


    播放声音


    let content = UNMutableNotificationContent()
    content.title = "WARNING: LOW BLOOD SUGAR"
    content.body = "Glucose level at 57."
    content.categoryIdentifier = "low-glucose—alert"
    content.sound = UNNotificationSound.criticalSoundNamed(@"warning-sound" withAudioVolume: 1.00)


    // Critical alert push payload

    {
      // Critical alert push payload

      {
          "aps" : {
              "sound" : {
                  "critical"1,
              }
          }
          "name""warning-sound.aiff",
          "volume"1.0
      }
    }


    总结


    至此WWDC中关于推送都已经整理完毕。大家有不懂的欢迎留言相互交流


    640?

    • 作者:FlyOceanFish

    • http://flyoceanfish.top

    • iOS开发整理发布,转载请联系作者获得授权

    640?wx_fmt=gif640?【点击成为源码大神】

    展开全文
  • iOS上简单推送通知(Push Notification)的实现 根据这篇很好的教程(http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12),结合自己的实践,写下一点笔记,仅供参考:) ...
    iOS上简单推送通知(Push Notification)的实现
    根据这篇很好的教程(http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12),结合自己的实践,写下一点笔记,仅供参考:)
    由于篇幅较长,我列出简单的目录,如下

    1) 理解Apple推送通知的机制
    2) 创建App ID
    3) 创建CSR文件
    4) 创建Provisioning Profile文件
    5) Xcode工程中取得Device Token


    [b]1、理解Apple推送通知的机制[/b]
    [img]http://dl2.iteye.com/upload/attachment/0105/8249/3e40d13e-c045-3f90-b5fa-fb2f65935a5c.jpg[/img]
    从上面的流程图中,可以看到一个能接收推送通知的App,需要3个东西:
    [list]
    [*]App ID(唯一标识一个App程序)
    [*]Provisioning Profile(App程序的发布需要它,所以推送通知只能在真机上测试)
    [*]Device Token(设备标识,这个是推送通知功能中特有的)
    [/list]
    而能推送通知的服务器端则要2个东西:
    [list]
    [*]SSL Certificate
    [*]Private Key
    [/list]
    (由于我对信息加密不清楚,所以这里不解释)

    值得注意的是APNS(ApplePush Notification Service) Server,完成发送Device Token和通知内容的功能,而且这2个动作都是被动的,即第一个动作是由App发起的,第二个则是推送通知的服务器发起的。
    对我而言,理解就这么多了。下面我按照参考文章进行实验。

    [b]2、创建App ID[/b]
    [img]http://dl2.iteye.com/upload/attachment/0105/8251/12adc4fe-11b6-3d94-8b14-710e49453cb1.jpg[/img]
    点击“New App ID”按钮后,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8253/0d601ecf-5054-37a1-8390-14d82700b2e3.jpg[/img]
    Description的内容可以任意,Bundle Identifier (App ID Suffix)必须和创建App工程时的Bundle Identifier,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8255/4da38b71-3b1e-3b49-b3df-63a570cdb760.jpg[/img]
    点击“Submit”后,点击左侧导航中的“App IDs”,找到刚才新创建的App ID,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8257/e26f4ed2-66f8-318c-9b7c-3b23a84510be.jpg[/img]
    点击“Configure”后,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8265/ede6e754-9a38-3823-9a24-309de6c78b3a.jpg[/img]
    勾选“Enable for Apple Push Notification service”,然后点击红色的“Configure”按钮,这里暂时只针对Development取得证书。弹出一个对话框,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8267/e4b9e06d-02ed-343a-9ac4-e0c3d8d83dd2.jpg[/img]
    点击“Continue”后,要我们上传一个CSR文件,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8270/661e1ad1-4cda-38e8-a996-21542c90dc36.jpg[/img]
    下面使用钥匙串访问(KeychainAccess)应用程序创建上面需要的CSR文件(.certSigningRequest文件)

    [b]3、创建CSR文件[/b]
    Keychain Access位于/Applications/Utilities目录中,打开它如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8272/32ebda0d-db2c-3d2a-83de-b6f7ae808388.jpg[/img]
    然后弹出窗口如下。
    [img]http://dl2.iteye.com/upload/attachment/0105/8274/618c4f37-1163-3ae9-b076-badbcb0591ca.jpg[/img]
    UserEmail Address随意写就可以,Common Name也是一样,注意勾选“Save to disks”,然后点击“Continue”。很快就生成好了所需文件,去找到它。
    [img]http://dl2.iteye.com/upload/attachment/0105/8276/748b8282-e8bf-3410-bf59-f9cf5482529c.jpg[/img]
    回到下面的网页中,上传刚才用KeychainAccess产生的HelloRemoteNotification.certSigningRequest文件。
    [img]http://dl2.iteye.com/upload/attachment/0105/8284/c91e00e0-a342-3737-9350-c6c787ace741.jpg[/img]
    很快需要的证书就OK了,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8288/00ac0973-48f0-3362-a659-e6ecde106801.jpg[/img]
    点击“Continue”,然后点击“Done”。
    [img]http://dl2.iteye.com/upload/attachment/0105/8300/ced8f96d-e7a2-323c-ac54-ff68550ee2cb.jpg[/img]
    发现上面的Status是Enabled,而且多了“Download”按钮,点击它,下载了一个名为“aps_development.cer”的文件。双击打开它,
    [img]http://dl2.iteye.com/upload/attachment/0105/8302/9d1966f1-189b-3d32-acfb-62d024fddb15.jpg[/img]
    找到上图中“Keys”栏中名为“HelloRemoteNotification”的private key(注意是private key,而不是public key),右击它,选择“Export “HelloRemoteNotification”…”,这样会导出一个.p12文件(需要输入密码),如下(目前共有3个文件)
    [img]http://dl2.iteye.com/upload/attachment/0105/8304/3e4bfd74-b257-3d9a-9e93-8d299d48b9cd.jpg[/img]
    下面开始用刚才产生的.p12文件,创建Profile provision文件

    [b]4、创建ProvisioningProfile文件[/b]
    [img]http://dl2.iteye.com/upload/attachment/0105/8306/514cc772-a110-3579-add3-2133efa3d6ad.jpg[/img]
    在上图中,点击“New Profile”按钮后,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8308/fe4f7dc2-3fab-372f-a58d-0b898b465457.jpg[/img]
    填写“Profile Name”;勾选“Certificate”;“App ID”选择正确的、之前我们创建的ID,即PushNotification;最后关联需要测试真机设备。点击“Submit”,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8310/88b1dcd2-1f8a-3fc3-9b1b-3824b3906dbf.jpg[/img]
    可以看到多了一个Provisioning Profile文件,点击“Download”按钮下载它,这时我们一共产生4个文件,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8312/58bc9318-77e7-3b4b-9e3f-48d96cd79634.jpg[/img]
    双击“PushNotification.mobileprovision”文件,或把它拖入到Xcode中。
    [img]http://dl2.iteye.com/upload/attachment/0105/8314/cf4ef723-ea76-3507-8df4-c80cb09c135d.jpg[/img]
    在Xcode中,找到Code Signing项,如上图,将Debug一项配置成刚才拖入Provisioning Profile对应的iPhone Developer。

    [b]5、Xcode工程中取得Device Token[/b]
    [img]http://dl2.iteye.com/upload/attachment/0105/8316/798b598e-6db2-31ee-b439-ec62f3329814.jpg[/img]
    在application:didFinishLaunchingWithOptions:方法里,注册使用远程通知。
    [img]http://dl2.iteye.com/upload/attachment/0105/8318/1559c855-17d1-36c7-a0f4-a6e2da55ac34.jpg[/img]
    添加2个方法,application: didRegisterForRemoteNotificationsWithDeviceToken:和application:didFailToRegisterForRemoteNotificationsWithError:,用于取得Device Token和打印错误。运行我们建的HelloRemoteNotification工程,如果以上步骤都正确,应该打印出Device Token,如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8320/f23face2-075c-323d-9412-41fbb07c4612.jpg[/img]
    也可能出错如下
    [img]http://dl2.iteye.com/upload/attachment/0105/8324/7ddfa6e3-a795-37c3-af94-0d0c253680ee.jpg[/img]
    展开全文
  • ——本地推送通知推送通知的作用?在App退到后台或者完全退出时,可以使用通知来告诉用户某件事情,比如推送新的聊天消息、新闻等通知对应的效果: 在主屏幕的顶端会出现通知消息 当手机锁屏时出现在锁屏界面,可以...
  • 需求ios developer文件(自行获取解决) aps_development.cer 推送证书 aps_development.p12 钥匙串导出的p12文件 ios_development.cer 开发者证书 CSRequest.certSigningRequest 从请求机构请求...
  • iOS推送流程(APNS)

    千次阅读 2017-12-04 14:33:15
    iOS推送流程(APNS)一、APNS(Apple Push Notification Service)苹果推送通知服务(APNs)是推送通知的网关,iPhone ipad 对于应用程序在后台运行有诸多限制,考虑到手机电池电量,应用不允许在后台进行过多的操作。...
  • ios推送通知

    2018-05-21 16:09:36
    具体流程如下:在Launchpad中找到我们钥匙串,在钥匙串中,打开Keychain Access &gt; Certificate Assistant &gt; Request a Certificate From a Certificate Authority… 菜单,如下图所示: 在弹出的...
  • iOS 推送通知

    2013-08-27 12:37:17
    本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义。 介绍一点点背景资料 众所周知,使用推送通知是一个很棒的、给应用添加实时消息通知的方式。这样做的结局是,开发者和用户...
  • iOS 推送通知的样式总结

    千次阅读 2017-12-24 23:27:53
    1. 推送通知 注意:这里说的推送通知跟NSNotification有所区别 ... iOS中提供了2种推送通知 本地推送通知(Local Notification) 远程推送通知(Remote Notification) 2. 推送通知的作用 可以让不在前
  • iOS推送通知实现

    千次阅读 2013-01-09 13:51:42
    iOS推送想必大家都很熟悉,在App没有在运行有新消息时顶部状态栏会出现提示信息,锁屏状态下会出现消息提示框,在App图标上也会有红色的角标。 当然这些提示方式用户是可以在设置中心定制的。 下面我就结合网上...
  • iOS 推送通知授权请求优化

    千次阅读 2016-06-25 20:33:46
    与直接打开app相比,用户更倾向于通过通知直接进入app丰富多彩的功能,所以不管是安卓用户还是iOS用户,推送通知已经成为用户与自己手机之间进行互动的主要方式之一。那么,锁屏时候的通知栏就理所当然成了争夺用户...
  • 摘要:这是一篇编译的文章...本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义。 介绍一点点背景资... 这是一篇编译的文章,内容均出自Parse.com的iOS开发教程,同时作者还提供了
  • iOS 推送通知详解

    2013-04-23 11:25:02
    本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义。 介绍一点点背景资料 众所周知,使用推送通知是一个很棒的、给应用添加实时消息通知的方式。这样做的结局是,开发者和...
  • iOS推送通知关闭

    千次阅读 2018-12-27 14:12:40
    - (void)registerRemoteNotification:(UIApplication *)application{      if ([[UIDevice currentDevice].systemVersion floatValue] &gt;= 10.0) ... //iOS10特有  UNUserNotificat...
  • 如何配置iOS推送通知

    2013-11-24 20:08:36
    配置推送通知比较麻烦,需要iOS开发者帐号,然后配置一个Apple ID、配置概要文件和SSL证书。   1 证书签名请求 首先需要证书签名请求,这需要在Mac OS X系统中完成,通过在系统中选择“实用...
  • iOS推送证书是用于推送 通知功能配置,需要配置到入极光推送、个推等推送平台。 iOS推送证书不能直接用于打包ipa,且推送证书只有p12,无关联描述文件。 iOS推送证书分为开发环境及生成环境,看下面具体申请步骤...
1 2 3 4 5 ... 20
收藏数 21,101
精华内容 8,440
关键字:

ios推送通知