1:UIWebView加载本地的HTML
NSString *path = [[NSBundle mainBundle] bundlePath]; NSURL *baseURL = [NSURL fileURLWithPath:path]; NSString * htmlPath = [[NSBundle mainBundle] pathForResource:@"index1" ofType:@"html"]; NSString * htmlCont = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; [self.webView loadHTMLString:htmlCont baseURL:baseURL];
注意:如何创建工程内的Css,js,html文件,创建iOS -other-Empty 如果Css 则以.css结尾,Js则以.js结尾,Html则是以.html结尾
2:JSPatch的运用
a:OC转JSPatch的地址:http://bang590.github.io/JSPatchConvertor/
b:JSPatch脚本介绍地址:https://github.com/bang590/JSPatch/wiki
c:比较不错的文章地址:ww.cnblogs.com/dsxniubility/p/5080875.html
d:JSPatch自动补地址:https://github.com/bang590/JSPatchX
注意版本控制(可以根据APP的版本号架服务端的请求地址)跟JS安全性(MD5加密然后再APP解密);
管理中心的一些考虑:
下面分享一个帮助类:
#import "JSPatchHelper.h" //文件名称 NSString * const jsPatchJsFileName=@"main.js"; @implementation JSPatchHelper + (instancetype)sharedInstance { static JSPatchHelper* instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [JSPatchHelper new]; }); return instance; } +(void)HSDevaluateScript { //从本地获取下载的JS文件 NSURL *p = FilePath; //判断文件是否存在 NSString *curFilePath=[p.path stringByAppendingString:[NSString stringWithFormat:@"/%@",jsPatchJsFileName]]; if (![[NSFileManager defaultManager] fileExistsAtPath:curFilePath]) { return; } //获取内容 NSString *js = [NSString stringWithContentsOfFile:curFilePath encoding:NSUTF8StringEncoding error:nil]; //如果有内容 if (js.length > 0) { //------- //服务端要对JS内容进行加密,在此处解密js内容;增加安全性 //---- //运行 [JPEngine startEngine]; [JPEngine evaluateScript:js]; } } +(void)loadJSPatch { //优化间隔一段时间 再去请求一次 否则太频繁(这边定义为一个小时才去请求一次) NSDate *myNowDate=[NSDate date]; if (!BBUserDefault.MBJsPatchTime) { BBUserDefault.MBJsPatchTime=myNowDate; return; } if ([myNowDate timeIntervalSinceDate:BBUserDefault.MBJsPatchTime]<3600) { return; } //使用AFNetWork下载在服务器的js文件 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:kJSPatchServerPath]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; if (httpResponse.statusCode==200) { NSURL *documentsDirectoryURL = FilePath; //保存到本地 Library/Caches目录下 return [documentsDirectoryURL URLByAppendingPathComponent:jsPatchJsFileName]; } else { return nil; } } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { NSLog(@"下载失败 to: %@", filePath); }]; [downloadTask resume]; } @end
详细的源代码可以到:https://github.com/wujunyang/MobileProject查看
class="s1">3:证书快要过期问题
第一步:如果开发者证书过期了的话,首先,打开密钥中心,生成一个CSR(证书请求)。然后,到Apple Center把证书revoke,然后新建一个,新建的将会默认是刚刚revoke的证书的所有设置的。把下载回来的证书导出一份p12格式的保存起来(因为如果其他人需要的时候,只能跟你拿了,在Apple Center下载的用不了的。)然后去provision profile edit 一下,从新下载,替换掉原来的。你就可以继续开发了(对外面已经安装的用户不会有影响)。
第二步:安装新的p12证书,并下载修改后的描述文件,如果本地已经安装以后的provisioning profile要先进行删除,可以进入~/Library/MobileDevice/Provisioning Profiles ,找到相应的文件进行删除,因为在文件里面它是以一串字符为命名,可以把旧证书先删除然后在Xcode里面打包,它会有提示这个provisioning profile的名字,删除就可以;然后在进行安装最新的provisioning profile,并选择相应证书就可以了;
4:给项目新建文件都默认增加前缀
5:iOS远程推送知识点
我们的设备联网时(无论是蜂窝联网还是Wi-Fi联网)都会与苹果的APNs服务器建立一个长连接(persistent IP connection),当Provider(我们自个的后台服务器,用于推送)推送一条通知的时候,这条通知并不是直接推送给了我们的设备,而是先推送到苹果的APNs服务器上面,而苹果的APNs服务器再通过与设备建立的长连接进而把通知推送到我们的设备上(参考图1-1,图1-2)。而当设备处于非联网状态的时候,APNs服务器会保留Provider所推送的最后一条通知,当设备转换为连网状态时,APNs则把其保留的最后一条通知推送给我们的设备;如果设备长时间处于非联网状态下,那么APNs服务器为其保存的最后一条通知也会丢失。Remote Notification必须要求设备连网状态下才能收到,并且太频繁的接收远程推送通知对设备的电池寿命是有一定的影响的。
deviceToken的生成:当一个App注册接收远程通知时,系统会发送请求到APNs服务器,APNs服务器收到此请求会根据请求所带的key值生成一个独一无二的value值也就是所谓的deviceToken,而后APNs服务器会把此deviceToken包装成一个NSData对象发送到对应请求的App上。然后App把此deviceToken发送给我们自己的服务器,就是所谓的Provider。Provider收到deviceToken以后进行储存等相关处理,以后Provider给我们的设备推送通知的时候,必须包含此deviceToken
远程推送内容
每一条通知的消息都会组成一个JSON字典对象,其格式如下所示,示例中的key值为苹果官方所用key。自定义字段的时候要避开这些key值。
{ "aps" : { "alert" : { // string or dictionary "title" : "string" "body" : "string", "title-loc-key" : "string or null" "title-loc-args" : "array of strings or null" "action-loc-key" : "string or null" "loc-key" : "string" "loc-args" : "array of strings" "launch-image" : "string" }, "badge" : number, "sound" : "string" "content-available" : number; "category" : "string" }, } aps:推送消息必须有的key alert:推送消息包含此key值,系统就会根据用户的设置展示标准的推送信息 badge:在app图标上显示消息数量,缺少此key值,消息数量就不会改变,消除标记时把此key对应的value设置为0 sound:设置推送声音的key值,系统默认提示声音对应的value值为default content-available:此key值设置为1,系统接收到推送消息时就会调用不同的回调方法,iOS7之后配置后台模式 category:UIMutableUserNotificationCategory's identifier 可操作通知类型的key值 title:简短描述此调推送消息的目的,适用系统iOS8.2之后版本 body:推送的内容 title-loc-key:功能类似title,附加功能是国际化,适用系统iOS8.2之后版本 title-loc-args:配合title-loc-key字段使用,适用系统iOS8.2之后版本 action-loc-key:可操作通知类型key值,不详细叙述 loc-key:参考title-loc-key loc-args:参考title-loc-args launch-image:点击推送消息或者移动事件滑块时,显示的图片。如果缺少此key值,会加载app默认的启动图片。
当然以上key值并不是每条推送消息都必带的key值,应当根据需求来选择所需要的key值,除了以上系统所提供的key值外,你还可以自定义自己的key值,来作为消息推送的负载,自定义key值与aps此key值并列。如下格式:
{ "aps" : { "alert" : "Provider push messag.", "badge" : 9, "sound" : "toAlice.aiff" }, "Id" : 1314, // 自定义key值 "type" : "customType" // 自定义key值 }
指定用户的推送
对于要求用户登录的App,推送是可以指定用户的,同一条推送有些用户可以收到,但是有些用户又不能收到。说起来这个就要提到另外的一个token了,一般称之为userToken,userToken一般都是根据自己公司自定义的规则去生成的。userToken是以用户的账号加对应的密码生成的。这样结合上面提到的deviceToken,就可以做到根据不同的用户推送不同的消息。deviceToken找到对应某台设备和该设备上的应用,而userToken对应找到该用户。客户端在上报deviceToken的时候,要把userToken对应一起上报给服务端也就是Provider。