1 - (void)showNotificationWithAction:(NSString *)action andContent:(NSString *)content 2 { 3 UILocalNotification *notification = [[UILocalNotification alloc] init]; 4 notification.alertBody = content; 5 notification.alertAction = action; 6 notification.soundName = UILocalNotificationDefaultSoundName; 7 [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; 8 } 9 10 - (void)scheduleNotificationWithItem:(ToDoItem *)item interval:(int)minutesBefore { 11 NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar]; 12 NSDateComponents *dateComps = [[NSDateComponents alloc] init]; 13 [dateComps setDay:item.day]; 14 [dateComps setMonth:item.month]; 15 [dateComps setYear:item.year]; 16 [dateComps setHour:item.hour]; 17 [dateComps setMinute:item.minute]; 18 NSDate *itemDate = [calendar dateFromComponents:dateComps]; 19 20 UILocalNotification *localNotif = [[UILocalNotification alloc] init]; 21 if (localNotif == nil) 22 return; 23 localNotif.fireDate = [itemDate dateByAddingTimeIntervalInterval:-(minutesBefore*60)]; 24 localNotif.timeZone = [NSTimeZone defaultTimeZone]; 25 26 localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"%@ in %i minutes.", nil), 27 item.eventName, minutesBefore]; 28 localNotif.alertAction = NSLocalizedString(@"View Details", nil); 29 30 localNotif.soundName = UILocalNotificationDefaultSoundName; 31 localNotif.applicationIconBadgeNumber = 1; 32 33 NSDictionary *infoDict = [NSDictionary dictionaryWithObject:item.eventName forKey:ToDoItemKey]; 34 localNotif.userInfo = infoDict; 35 36 [[UIApplication sharedApplication] scheduleLocalNotification:localNotif]; 37 }
处理Local Notification
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 2 { 3 NSLog(@"Start App...."); 4 .... 5 UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; 6 if ([self isWelcomeNotification:localNotification]) { 7 NSLog(@"start with welcome notification"); 8 [self.mainViewController showOfficeIntroduction]; 9 } 10 return YES; 11 }
2. App运行在后台
1 - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 2 { 3 if ([self isWelcomeNotification:notification]) { 4 [self.mainViewController showOfficeIntroduction]; 5 }if ([self isCustomerDataNotification:notification]) { 6 [self.mainViewController showCustomerDataIntroduction]; 7 } 8 }
1 if ( UIApplication . instancesRespondToSelector ( Selector ( "registerUserNotificationSettings:" ))) { 2 3 application. registerUserNotificationSettings ( UIUserNotificationSettings (forTypes: UIUserNotificationType .Sound | UIUserNotificationType .Alert | UIUserNotificationType .Badge, categories: nil )) 4 5 } else { 6 7 application. registerForRemoteNotificationTypes (.Alert | .Sound | .Badge) 8 9 } 10 11 然后,在Appdelegate.swift 写相关远程推送、本地通知等代码 12 13 // 收到本地通知 14 15 func application(application: UIApplication , didReceiveLocalNotification notification: UILocalNotification ) { 16 17 var alertView = UIAlertView (title: " 系统本地通知 " , message: notification. alertBody , delegate: nil , cancelButtonTitle: " 返回 " ) 18 19 alertView. show () 20 21 }
本地通知方法:
1 ****************************** 本地通知方法 ********** ***** *************** 2 3 // 4 5 // TimeViewController.swift 6 7 // UIControlDemo 8 9 // 10 11 // Created by on 14/12/10. 12 13 // Copyright (c) 2014 年 马大哈 . All rights reserved. 14 15 // 16 17 import UIKit 18 19 class TimeViewController: BaseViewController { 20 21 var wordTextField: UITextField ? // 文字 22 23 var dateTextField: UITextField ? // 时间 24 25 var datePicker: UIDatePicker ? 26 27 override func viewDidLoad() { 28 29 super . viewDidLoad () 30 31 self . title = " 时间 / 日期 / 本地通知 " 32 33 let leftBarButton: UIBarButtonItem = UIBarButtonItem (barButtonSystemItem: . Trash , target: self , action: "locaNotifcationDeleteAll" ) 34 35 self . navigationItem . rightBarButtonItem = leftBarButton; 36 37 wordTextField = UITextField (frame: CGRectMake ( 50 , 80 , 200 , 40 )) 38 39 wordTextField ?. backgroundColor = . clearColor () 40 41 wordTextField !. tag = 100 42 43 wordTextField ?. borderStyle = UITextBorderStyle . RoundedRect 44 45 wordTextField ?. keyboardType = UIKeyboardType . Default 46 47 wordTextField ?. returnKeyType = UIReturnKeyType . Done 48 49 wordTextField ?. contentVerticalAlignment = UIControlContentVerticalAlignment . Center 50 51 wordTextField ?. clearButtonMode = UITextFieldViewMode . WhileEditing 52 53 wordTextField ?. secureTextEntry = false 54 55 wordTextField ?. textColor = . blackColor () 56 57 wordTextField ?. textAlignment = . Left 58 59 wordTextField ?. placeholder = " 键盘 " 60 61 wordTextField ?. font = UIFont . systemFontOfSize ( 15 ) 62 63 self . view . addSubview ( wordTextField !) 64 65 dateTextField = UITextField (frame: CGRectMake ( 50 , 140 , 200 , 40 )) 66 67 dateTextField ?. backgroundColor = . clearColor () 68 69 dateTextField !. tag = 101 70 71 dateTextField ?. borderStyle = UITextBorderStyle . RoundedRect 72 73 dateTextField ?. keyboardType = UIKeyboardType . Default 74 75 dateTextField ?. returnKeyType = UIReturnKeyType . Done 76 77 dateTextField ?. contentVerticalAlignment = UIControlContentVerticalAlignment . Center 78 79 dateTextField ?. textColor = . blackColor () 80 81 dateTextField ?. textAlignment = . Left 82 83 dateTextField ?. placeholder = " 日期 picker" 84 85 dateTextField ?. font = UIFont . systemFontOfSize ( 15 ) 86 87 self . view . addSubview ( dateTextField !) 88 89 90 91 datePicker = UIDatePicker () 92 93 datePicker ?. datePickerMode = . DateAndTime 94 95 datePicker ?. timeZone = NSTimeZone . systemTimeZone () 96 97 datePicker ?. addTarget ( self , action: "datePickerSelected:" , forControlEvents: UIControlEvents .ValueChanged) 98 99 dateTextField !. inputView = datePicker 100 101 102 103 var button = UIButton . buttonWithType ( UIButtonType . Custom ) as UIButton 104 105 button. frame = CGRectMake ( 200 , 200 , 50 , 30 ) 106 107 button. backgroundColor = UIColor . redColor () 108 109 button. setTitleColor ( UIColor . blackColor (), forState:.Normal) 110 111 button. setTitle ( " 保存 " , forState: UIControlState .Normal) 112 113 button. titleLabel !. font = UIFont . boldSystemFontOfSize ( CGFloat ( 20 )) 114 115 button. showsTouchWhenHighlighted = true 116 117 button. addTarget ( self , action: "saveLocalNotificationButton" , forControlEvents: UIControlEvents .TouchUpInside) 118 119 self . view . addSubview (button) 120 121 } 122 123 // 保存按钮方法 124 125 func saveLocalNotificationButton(){ 126 127 var contentDic = [ "KEY" : "VALUE" ] 128 129 locaNotifcationSchedule (chedulDate: datePicker !. date , alertBody: " 通知看到 : /( wordTextField !. text ) " , content: contentDic) 130 131 var alertView = UIAlertView (title: " 保存成功 " , message: nil , delegate: nil , cancelButtonTitle: " 返回 " ) 132 133 alertView. show () 134 135 wordTextField ?. resignFirstResponder () 136 137 dateTextField ?. resignFirstResponder () 138 139 } 140 141 142 143 // 注册本地通知 144 145 func locaNotifcationSchedule(#chedulDate: NSDate ,alertBody: String ,content: NSDictionary ) { 146 147 var localNotif = UILocalNotification () 148 149 localNotif. fireDate = chedulDate 150 151 localNotif. timeZone = NSTimeZone . defaultTimeZone () 152 153 // localNotif.repeatInterval = repeatInterval 0 代表不重复 154 155 localNotif. soundName = "iPhone.caf" // 此属性可以不写(默认系统声音 UILocalNotificationDefaultSoundName ) 156 157 // localNotif.hasAction = true; 158 159 // localNotif.alertAction = " 查看 "; 160 161 localNotif. alertBody = alertBody 162 163 localNotif. userInfo = content 164 165 UIApplication . sharedApplication (). scheduleLocalNotification (localNotif) 166 167 } 168 169 // 删除所有注册的本地通知 170 171 func locaNotifcationDeleteAll() { 172 173 let application = UIApplication . sharedApplication () 174 175 application. cancelAllLocalNotifications () 176 177 var alertView = UIAlertView (title: " 所有本地通知都已移除 " , message: nil , delegate: nil , cancelButtonTitle: " 返回 " ) 178 179 alertView. show () 180 181 } 182 183 // 动态改变 textfield 内容 184 185 func datePickerSelected(datePicker: UIDatePicker ){ 186 187 let dateString = timeDateFormatter (). stringFromDate (datePicker. date ) 188 189 dateTextField !. text = dateString 190 191 } 192 193 override func touchesEnded(touches: NSSet , withEvent event: UIEvent ) { 194 195 wordTextField ?. resignFirstResponder () 196 197 dateTextField ?. resignFirstResponder () 198 199 } 200 201 override func didReceiveMemoryWarning() { 202 203 super . didReceiveMemoryWarning () 204 205 } 206 207 }
首先是申请证书的网址
https://developer.apple.com/ios/manage/overview/index.action
登录成功以后,进入iOS 配置管理的 主页面.
第一步操作是去创建一个新的App IDs创建成功后,会需要提供安全证书来激动推送服务,如下图:
选择存储到磁盘以后,生成一个文件名称为(简称CSR): CertificateSigningRequest.certSigningRequest
回到Apple页面 将这个提交并提示激动成功.
激活成功后的App IDs 提供下载开发版或是发布版的主动推送证书(aps_development.cer),如果需要做服务器方面的主动推送的话,就必须要下载这个文件来使用推送服务了.
第二步要为App提供接受推送许可的证书,点击Provisioning进行设置,添加一个新的许可,选择刚刚新创建的App IDs. 再选择可以调试的iPhone 设备.
最后,同样是下载下来: YsyPushMessageDemo.mobileprovision双击该证书,让其加载一次.
接下来,进入iOS工程,选择使用该证书来调试.
红圈中,全部设置刚刚加载的许可证书.
那么到这里,关于证书类的准备工作,已经全部准备就绪.
在这里再此强调一次,每个文件的具体作用
1: CertificateSigningRequest.certSigningRequest : 为生成App IDs 而用
2: aps_development.cer 为开发主动推送服务而用到的证书
3: YsyPushMessageDemo.mobileprovision 为App 接受推送通知的许可服务
主动推送的Push 代码及使用,请参考一开始介绍的第一篇博客
这里只附上下载地址: https://github.com/stefanhafeneger/PushMeBaby
接下来,说说收到推送通知代码方面.
1:申请本App需要接受来自服务商提供推送消息,
1 //远程通知注册成功委托 2 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 3 { 4 NSLog(@"%@",deviceToken); 5 self.viewController.toKenValueTextView.text = [NSString stringWithFormat:@"%@",deviceToken]; 6 self.viewController.pushStatusLabel.text = @"已经注册."; 7 } 8 //远程通知注册失败委托 9 -(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 10 { 11 self.viewController.toKenValueTextView.text = [error description]; 12 }
1 //点击某条远程通知时调用的委托 如果界面处于打开状态,那么此委托会直接响应 2 -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 3 { 4 NSLog(@"远程通知"); 5 [self PMD_uesPushMessage:userInfo]; 6 }
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 2 { 3 //这里处理应用程序如果没有启动,但是是通过通知消息打开的,此时可以获取到消息. 4 if (launchOptions != nil) { 5 NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; 6 [self PMD_uesPushMessage:userInfo]; 7 } 8 return YES; 9 }
5:清空通知中心已有的推送消息,只需要将指定App 的 Badge 设置为 0即可
6:主动推送的字符串必须符合如下Json数组的格式,才能正确推送到手机当中.
1 @"{ 2 3 //自定义参数 4 5 "userinfo": 6 7 { 8 9 "name":"remote notice" 10 11 }, 12 13 //标准写法 14 15 "aps": 16 17 { 18 19 "alert": 20 21 { 22 23 "action-loc-key":"Open",//支持多语言 24 25 "body":"messgae content"//消息正文 26 27 }, 28 29 "badge":1,//为App 的icon 标记 具体数值 30 31 "sound":"default" //播放的音频文件,default 表示系统默认的选择列铃声 32 33 } 34 35 }";
到这里就差不多结束了.
php服务器推送消息
1 <?php 2 3 $deviceToken = '38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7ce90d56e9 fe145bcc 6c2c594b'; // masked for security reason 4 // Passphrase for the private key (ck.pem file) 5 // $pass = ''; 6 // Get the parameters from http get or from command line 7 $message = $_GET['message'] or $message = $argv[1] or $message = 'Message received from javacom'; 8 $badge = (int)$_GET['badge'] or $badge = (int)$argv[2]; 9 $sound = $_GET['sound'] or $sound = $argv[3]; 10 // Construct the notification payload 11 $body = array(); 12 $body['aps'] = array('alert' => $message); 13 if ($badge) 14 $body['aps']['badge'] = $badge; 15 if ($sound) 16 $body['aps']['sound'] = $sound; 17 18 19 $ctx = stream_context_create(); 20 stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem'); 21 // assume the private key passphase was removed. 22 // stream_context_set_option($ctx, 'ssl', 'passphrase', $pass); 23 $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); 24 if (!$fp) { 25 print "Failed to connect $err $errstrn"; 26 return; 27 } 28 else { 29 print "Connection OKn"; 30 } 31 $payload = json_encode($body); 32 $msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload; 33 print "sending message :" . $payload . "n"; 34 fwrite($fp, $msg); 35 fclose($fp); 36 ?>
1 // 远程推送通知 注册成功 2 3 func application(application: UIApplication , didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData ) { 4 5 println (deviceToken. description ) 6 7 } 8 9 // 远程推送通知 注册失败 10 11 func application(application: UIApplication , didFailToRegisterForRemoteNotificationsWithError error: NSError ) { 12 13 if error. code == 3010 { 14 15 println ( "Push notifications are not supported in the iOS Simulator." ) 16 17 } else { 18 19 println ( "application:didFailToRegisterForRemoteNotificationsWithError: /(error) " ) 20 21 } 22 23 } 24 25 // 8.0 之前 收到远程推送通知 26 27 func application(application: UIApplication , didReceiveRemoteNotification userInfo: [ NSObject : AnyObject ]) { 28 29 let notif = userInfo as NSDictionary 30 31 let apsDic = notif. objectForKey ( "aps" ) as NSDictionary 32 33 let alertDic = apsDic. objectForKey ( "alert" ) as String 34 35 var alertView = UIAlertView (title: " 系统本地通知 " , message: alertDic, delegate: nil , cancelButtonTitle: " 返回 " ) 36 37 alertView. show () 38 39 } 40 41 // 8.0 之后 收到远程推送通知 42 43 func application(application: UIApplication , didReceiveRemoteNotification userInfo: [ NSObject : AnyObject ], fetchCompletionHandler completionHandler: ( UIBackgroundFetchResult ) -> Void ) { 44 45 let notif = userInfo as NSDictionary 46 47 let apsDic = notif. objectForKey ( "aps" ) as NSDictionary 48 49 let alertDic = apsDic. objectForKey ( "alert" ) as String 50 51 var alertView = UIAlertView (title: " 远程推送通知 " , message: alertDic, delegate: nil , cancelButtonTitle: " 返回 " ) 52 53 alertView. show () 54 55 } 56 57 // 注册通知 alert 、 sound 、 badge ( 8.0 之后,必须要添加下面这段代码,否则注册失败) 58 59 func application(application: UIApplication , didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings ) { 60 61 application. registerForRemoteNotifications () 62 63 }