新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > iOS 7: 隐藏的特性和解决之道

iOS 7: 隐藏的特性和解决之道

作者: 时间:2016-09-12 来源:网络 收藏

}];

当手机从edge环境到3G,log输出应该像这样:

iOS7Tests[612:60b] Current Radio Access Technology: CTRadioAccessTechnologyEdge

iOS7Tests[612:1803] New Radio Access Technology: (null)

iOS7Tests[612:1803] New Radio Access Technology: CTRadioAccessTechnologyHSDPA

苹果导出了所有字符串符号,因此可以很简单的比较和检测当前的网络信息。

Core Foundation 和 Autorelease

Core Foundation中出现了一个新的方法,它被用于私有调用已有数年时间:

CFTypeRef CFAutorelease(CFTypeRef CF_RELEASES_ARGUMENT arg)

它确实做了你所期望的事,让人费解的是苹果花了这么长时间才把它公开。ARC 下,大多数人在处理返回 Core Foundation 对象时是通过转换成对等的 NS 对象来完成的,如 NSDictionary,即便它只是一个 CFDictionaryRef 然后简单地 CFBridgingRelease() 。这样通常没问题,除非你返回的对等 NS 对象不可用时,如 CFBagRef。你要么使用 id,这样会失去类型安全性,要么你将你的方法重命名为 createMethod 并考虑所有的内存语义,最后使用 CFRelease。还有一些手段,比如这个,用 non-ARC-file 标签然后编译,但终归得使用CFAutorelease()。另外:不要编写使用苹果公司命名空间的代码,所有这些自定义的 CF-宏将来都会被打破的。

图片解压缩

当通过 UIImage 展示一张图时,在显示之前需要解压缩(除非源已经像素缓存了)。对于 JPG/PNG 文件这会占用相当可观的时间并会造成卡顿。iOS6 以前,通常是创建一个位图上下文,然后在其中画图来解决。(参见 AFNetworking 如何处理)。

iOS7 开始,你可以使用kCGImageSourceShouldCacheImmediately:来强制图片在创建时立即解压缩:

(UIImage *)decompressedImageWithData:(NSData *)data

{

CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);

CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)@{(id)kCGImageSourceShouldCacheImmediately: @YES});

UIImage *image = [UIImage imageWithCGImage:cgImage];

CGImageRelease(cgImage);

CFRelease(source);

return image;

}

当我刚发现这一点时确实很兴奋,但事实并非如此。在我的测试中,发现当开启了即时缓存后性能有明显的降低。要么这个方法是在主线程中调用的(不太可能),感觉上性能更糟,因为它在方法copyImageBlockSetJPEG中锁住了,而同时在主线程中在显示非加密的图片所致。在我的程序中,我在主线程中加载小的预览图,在后台线程中加载大型图,使用了kCGImageSourceShouldCacheImmediately后小小的解压缩阻塞了主线程,同时在后台处理大量开销昂贵的操作。

还有更多关于图片解压缩相关的却不是 iOS7 中的新东西,像kCGImageSourceShouldCache,它用来控制系统自动卸载解压缩的图片数据的能力。确保你将它设置为YES,否则所有的工作都将没有意义。有趣的是,苹果在64bit运行时的系统中将kCGImageSourceShouldCache的默认值从 NO 改为了 YES。

盗版检查

苹果添加了一个方式,通过 NSBunble 上的新方法appStoreReceiptURL来评估Lion系统上 App Store 的收据,同时也将其移植到了 iOS 上。这使得你可以检查你的应用是在被合法购买或者已经被破解了。检查收据还有一个重要的原因,它包含了初始购买日期,这点对于把你的应用从付费模型迁移到免费+应用内付费方式很有帮助意义。你可以根据这个初始购买日期来决定额外内容对于你的用户是免费的还是收费的。

收据还允许你检查应用程序是否通过批量购买计划购买以及该许可证是否仍有效,有一个名为SKReceiptPropertyIsVolumePurchase的属性显示了该值。

当你调用appStoreReceiptURL时,你需要特别注意,因为在 iOS6 上,它还是一个私有API,你应该在用户代码中先调用doesNotRecognizeSelector:,在调用前检查运行(基础)版本。在开发期间,这个方法返回的 URL 不会是指向一个文件。你可能需要使用 StoreKit 的SKReceiptRefreshRequest,这也是 iOS7 中的新东西,用它来下载证书。使用一个至少购买过一次的测试用户,否则它将没法工作:

Refresh the Receipt

SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init];

[request setDelegate:self];

[request start];

验证收据需要大量的代码。你需要使用OpenSSL和内嵌的苹果根证书,并且你还要了解一些基本的东西像是证书、PCKS容器以及ASN.1。这里有一些样例代码,但是你不应该让它这么简单——别只是拷贝现有的验证方法,至少做点修改或者编写你自己的,你应该不希望一个普通的补丁程序就能在数秒内瓦解你的努力吧。

你绝对应该读读苹果的指南——验证 Mac App 商店收据,这里面的大多数都适用于 iOS。苹果在 WWDC2013 的 Session308 “Using Receipts to Protect Your Digital Sales” 中详述了“Grand Unified Receipt”的变动。

Comic Sans MS

iOS7 中,终于迎回了 Comic Sans MS。现在,它以可下载的字体被添加到 iOS6 中,但当时的字体列表很少也不见得多么有趣。在 iOS7 中苹果添加了不少字体,包括“famous”,它和 PT Sans 或 Comic Sans MS 有些类似。kCTFontDownloadableAttribute并没有在 iOS6 中声明,所以 iOS7 以前它并不真正可用,但苹果确是在 iOS6 的时候就已经做了私有声明了。

字体列表是动态变化的,以后可能就会发生变动。苹果在 Tech Note HT5484 中罗列了一些可用的字体,但这个文档已经过时了,同时也不能反映 iOS7 的变化。



关键词:

评论


相关推荐

技术专区

关闭