application.applicationIconBadgeNumber = N; // 设为0隐藏图标数字
// 从应用打开一个网页
NSString *url = @"http://tadu.com";
[application openURL:[NSURL URLWithString:url]];
// Save the token to server
NSString *urlStr = [NSString stringWithFormat:@"https://%@/push_token", @"tdpush.ap01.aws.af.cm"];
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:@"POST"];
[req setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"username=%@", @"JacksonTian"]
dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"&token=%@",
pushToken] dataUsingEncoding:NSUTF8StringEncoding]];
[req setHTTPBody:postBody];
NSURLConnection *conn = [[NSURLConnection alloc] init];
(void)[conn initWithRequest:req delegate:nil];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
用户确认接收:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
NSString *tokenStr = [deviceToken description];
NSString *pushToken = [[[tokenStr stringByReplacingOccurrencesOfString:@"<" withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""]
stringByReplacingOccurrencesOfString:@" " withString:@""];
}
接收到token后,需要将数据提交到服务端,服务端才能通过APNS向用户设备发送通知。 用户拒绝接收:
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"Failed to get token, error: %@", error);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (launchOptions != nil)
{
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSLog(@"Launched from push notification: %@", dictionary);
}
}
return YES;
}
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
NSLog(@"Received notification: %@", userInfo);
}
设定一个时间发出通知。本地通知只在应用在后台运行时才会出现
UILocalNotification *notification = [[UILocalNotification alloc] init];
if (notification!=nil) {
NSLog(@">> support local notification");
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.alertBody = @"该去吃晚饭了!";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(@"收到本地通知");
}
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
在创建Connection建立的时候传递请求对象和委托对象。委托对象需要实现NSURLConnectionDataDelegate
协议。具体方法如下:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
didReceiveResponse
在响应开始时触发。didReceiveData
在收到数据包时触发。connectionDidFinishLoading
在响应结束后触发。
接收数据时要在didReceiveResponse
中准备接收数据的容器,在didReceiveData
中将数据块装入容器,在connectionDidFinishLoading
中整个倒出来使用。
一般而言HTTP和HTTPS都不会遇到这个问题,只要实现NSURLConnectionDataDelegate
协议就能完成需求。但是对于自签名证书,NSURLConnection
对象无法验证服务端证书的真伪。这个时候需要动用到NSURLConnectionDelegate
协议。
具体方法是以下几个:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)prote
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
其中canAuthenticateAgainstProtectionSpace
如果返回No,将由系统自行处理。返回YES将会由后续的didReceiveAuthenticationChallenge
处理。默认为No。
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
NSLog(@"处理证书");
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
在didReceiveAuthenticationChallenge
中我们要通过challenge
的sender
告知是否信任服务端的证书。
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if (trusted) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
} else {
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}
我们可以设定trusted
来判定是否信任。可以直接设置为YES来表示信任服务端。但是直接设置是不严谨的,并没有验证服务端证书的真伪。
在连接建立后,我们可以拿到服务端的证书。要验证它的真伪需要我们用CA的证书来进行判定。
// 获取der格式CA证书路径
NSString *certPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"der"];
// 提取二进制内容
NSData *derCA = [NSData dataWithContentsOfFile:certPath];
// 根据二进制内容提取证书信息
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)derCA);
// 形成钥匙链
NSArray * chain = [NSArray arrayWithObject:(__bridge id)(caRef)];
caChainArrayRef = CFBridgingRetain(chain);
// 取出服务器证书
SecTrustRef trust = [[challenge protectionSpace] serverTrust];
SecTrustResultType trustResult = 0;
// 设置为我们自有的CA证书钥匙连
int err = SecTrustSetAnchorCertificates(trust, caChainArrayRef);
if (err == noErr) {
// 用CA证书验证服务器证书
err = SecTrustEvaluate(trust, &trustResult);
}
CFRelease(trust);
// 检查结果
BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed)||(trustResult == kSecTrustResultConfirm) || (trustResult == kSecTrustResultUnspecified));
UIWebView不能处理自签名的证书,需要在它发起访问之前通过上述的方法进行证书的设置判定,之后再通过UIWebView进行访问即可通过。