可爱熊个人博客

Archive for 二月, 2012

程序内购买(IAP)详解【转载】

一、In App Purchase概览

Store Kit代表App和App Store之间进行通信。
程序将从App Store接收那些你想要提供的产品的信息,并将它们显示出来供用户购买。
当用户需要购买某件产品时,程序调用StoreKit来收集购买信息。
Store Kit的API只是为程序添加In App Purchase功能的一小部分。你需要决定如何去记录那些你想要提交的产品,如何在程序中将商店功能展现给用户,还要考虑如何将用户购买的产品提交。本章的剩余部分会展示整个流程。

Products
产品可以是任意一项你想要出售的特性。产品在iTunes Connect中被组织,这和你添加一个新的App是一样的。支持的产品种类共有四种:
1. 内容型。包括电子书,电子杂志,照片,插图,游戏关卡,游戏角色,和其他的数字内容。
2. 扩展功能。这些功能已经包含在App内部。在未购买之前被锁定。例如,你可以在一个游戏程序中包含若干个小游戏,用户可以分别来购买这些游戏。
3. 服务。允许程序对单次服务收费。比如录音服务。
4. 订阅。支持对内容或服务的扩展访问。例如,你的程序可以每周提供财务信息或游戏门户网站的信息。应该设定一个合理的更新周期,以避免过于频繁的
提示困扰用户。要记住:你将负责跟踪订阅的过期信息,并且管理续费。App Store不会替你监视订阅的周期,也不提供自动收费的机制。

In App Purchase为创建产品提供了一种通用的机制,如何操作将由你负责。当你设计程序的时候,有以下几点需要注意:

1. 你必须提供电子类产品和服务。不要使用In App Purchase 去出售实物和实际服务。
2. 不能提供代表中介货币的物品,因为让用户知晓他们购买的商品和服务是很重要的。 Read More…

苹果购买信息的键

键名 描述
quantity 购买商品的数量。对应SKPayment对象中的quantity属性
product_id 商品的标识,对应SKPayment对象的productIdentifier属性。
transaction_id 交易的标识,对应SKPaymentTransaction的transactionIdentifier属性
purchase_date 交易的日期,对应SKPaymentTransaction的transactionDate属性
original_-transaction_id 对于恢复的transaction对象,该键对应了原始的transaction标识
original_purchase_-date 对于恢复的transaction对象,该键对应了原始的交易日期
app_item_id App Store用来标识程序的字符串。一个服务器可能需要支持多个server的支付功能,可以用这个标识来区分程序。链接sandbox用来测试的程序的不到这个值,因此该键不存在。
version_external_-identifier 用来标识程序修订数。该键在sandbox环境下不存在
bid iPhone程序的bundle标识
bvrs iPhone程序的版本号

php修改文件名函数

修改文件名的函数,rename($o,$n),$o是旧文件名,$n要被修改成的新文件名哦。下面我们来看一款关于重名命文件名的实例

<?php session_start();
if($submit==”提交”){
if (file_exists( $old_name)){
if (rename($old_name,$new_name )) //把原文件重新命名
{echo “修改成功!”;}
}else{ print $old_name.”文件不存在!<br>” ; }
}
?>

为UIWebView实现离线浏览

智能手机的流行让移动运营商们大赚了一笔,然而消费者们却不得不面对可怕的数据流量账单。因为在线看部电影可能要上千块通讯费,比起电影院什么的简直太坑爹了。
所以为了减少流量开销,离线浏览也就成了很关键的功能,而UIWebView这个让人又爱又恨的玩意弱爆了,居然只在Mac OS X上提供webView:resource:willSendRequest:redirectResponse:fromDataSource:这个方法,于是只好自己动手实现了。

原理就是SDK里绝大部分的网络请求都会访问[NSURLCache sharedURLCache]这个对象,它的cachedResponseForRequest:方法会返回一个NSCachedURLResponse对象。如果这个NSCachedURLResponse对象不为nil,且没有过期,那么就使用这个缓存的响应,否则就发起一个不访问缓存的请求。
要注意的是NSCachedURLResponse对象不能被提前释放,除非UIWebView去调用NSURLCache的removeCachedResponseForRequest:方法,原因貌似是UIWebView并不retain这个响应。而这个问题又很头疼,因为UIWebView有内存泄露的嫌疑,即使它被释放了,也很可能不去调用上述方法,于是内存就一直占用着了。

顺便说下NSURLRequest对象,它有个cachePolicy属性,只要其值为NSURLRequestReloadIgnoringLocalCacheData的话,就不会访问缓存。可喜的是这种情况貌似只有在缓存里没取到,或是强制刷新时才可能出现。
实际上NSURLCache本身就有磁盘缓存功能,然而在iOS上,NSCachedURLResponse却被限制为不能缓存到磁盘(NSURLCacheStorageAllowed被视为NSURLCacheStorageAllowedInMemoryOnly)。
不过既然知道了原理,那么只要自己实现一个NSURLCache的子类,然后改写cachedResponseForRequest:方法,让它从硬盘读取缓存即可。

于是就开工吧。这次的demo逻辑比较复杂,因此我就按步骤来说明了。

先定义视图和控制器。
它的逻辑是打开应用时就尝试访问缓存文件,如果发现存在,则显示缓存完毕;否则就尝试下载整个网页的资源;在下载完成后,也显示缓存完毕。
不过下载所有资源需要解析HTML,甚至是JavaScript和CSS。为了简化我就直接用一个不显示的UIWebView载入这个页面,让它自动去发起所有请求。
当然,缓存完了还需要触发事件来显示网页。于是再提供一个按钮,点击时显示缓存的网页,再次点击就关闭。
顺带一提,我本来想用Google为例的,可惜它自己实现了HTML 5离线浏览,也就体现不出这种方法的意义了,于是只好拿百度来垫背。

Read More…