<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>RichMedia+ &#187; Adobe Air</title>
	<atom:link href="http://blog.richmediaplus.com/tag/adobe-air/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.richmediaplus.com</link>
	<description>About the Adobe&#039;s RIA related solution and technology, like Adobe Air, Adobe Flex, Mobile Dev. You also can find the SEO for Flex, RIA, User Ex in this blog.</description>
	<lastBuildDate>Fri, 16 Dec 2011 09:33:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</title>
		<link>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/</link>
		<comments>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 01:30:10 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[ActionScript3]]></category>
		<category><![CDATA[Air]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash/Flex Mobile Dev]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Dev]]></category>
		<category><![CDATA[Adobe Air]]></category>
		<category><![CDATA[AIR Native Extension]]></category>
		<category><![CDATA[In App Purchase]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=840</guid>
		<description><![CDATA[原文链接： AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发 本文的内容如下： 在Native扩展中使用StoreKit框架 ActionScript扩展 ANE－IAP开发实例分享 本文用到的工具和设备如下： Flash Builder 4.5 Flex SDK 4.5.1 Flash Professional CS5.5 AIR SDK 3.0 Xcode 4.1 + iOS SDK 4.3 iPad 1 本文例子中的Objective-C部分和AS扩展类库部分的代码作者为我的同事Saumitra Bhave ———————————————————————————– 在Native扩展中使用StoreKit框架 下载安装XCode 4和iOS SDK之后，让我们先来了解一下苹果原生类库是如何处理应用内付费功能的。iOS SDK中有一个框架叫做StoreKit，它负责应用程序和应用商店的业务流程。StoreKit中有一些负责具体功能的类，商品的请求，请求结果，结果回调，购买，购买队列等都由不同的类来完成。 如上图所示，StoreKit解决内付费业务的大体流程可以概括成这样，SKProductsRequest向商店发出请求获得商品信息，商店通过回调函数SKProductsRequestDelegate把请求的结果SKProductsReponse传了回来，如果用户选择购买商品，则创建一个SKPayment实例到购买队列SKPaymentQueue中，然后通过回调SKPaymentTransactionObserver来返回购买的结果。 我现在拿请求商品信息的部分来举例说明一下： SKProductsRequest* req = &#91;&#91;SKProductsRequest alloc&#93; initWithProductIdentifiers:pids&#93;; req.delegate = observer; &#91;req start&#93;; 上面的Objective-C的代码如果转译成ActionScript 3.0，相当于这个意思： var req:SKProductsRequest [...]
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step2/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>原文链接：<br />
<a title="Permanent Link to AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发" href="http://jamesli.cn/blog/?p=1179" rel="bookmark">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></p>
<p><strong>本文的内容如下：</strong></p>
<ul>
<li>在Native扩展中使用StoreKit框架</li>
<li>ActionScript扩展</li>
<li>ANE－IAP开发实例分享</li>
</ul>
<p><strong>本文用到的工具和设备如下：</strong><br />
<a href="http://www.adobe.com/products/flash-builder-family.html" target="_blank">Flash Builder 4.5</a><br />
<a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4.5" target="_blank">Flex SDK 4.5.1</a><br />
<a href="http://www.adobe.com/products/flash.html" target="_blank">Flash Professional CS5.5</a><br />
<a href="http://www.adobe.com/special/products/air/sdk/" target="_blank">AIR SDK 3.0</a><br />
<a href="https://developer.apple.com/devcenter/ios/index.action" target="_blank">Xcode 4.1 + iOS SDK 4.3</a><br />
iPad 1</p>
<p><strong>本文例子中的Objective-C部分和AS扩展类库部分的代码作者为我的同事<a href="http://saumitrabhave.com/" target="_blank">Saumitra Bhave</a></strong><br />
———————————————————————————–<br />
<span style="color: #ff0000;"><strong>在Native扩展中使用StoreKit框架</strong></span></p>
<p>下载安装XCode 4和iOS SDK之后，让我们先来了解一下苹果原生类库是如何处理应用内付费功能的。iOS SDK中有一个框架叫做StoreKit，它负责应用程序和应用商店的业务流程。StoreKit中有一些负责具体功能的类，商品的请求，请求结果，结果回调，购买，购买队列等都由不同的类来完成。<br />
<img class="alignnone size-full wp-image-843" title="图1 StoreKit的业务流程" src="http://blog-uploads.richmediaplus.com/2011/10/storekit.png" alt="StoreKit的业务流程" width="486" height="350" /><br />
如上图所示，StoreKit解决内付费业务的大体流程可以概括成这样，SKProductsRequest向商店发出请求获得商品信息，商店通过回调函数SKProductsRequestDelegate把请求的结果SKProductsReponse传了回来，如果用户选择购买商品，则创建一个SKPayment实例到购买队列SKPaymentQueue中，然后通过回调SKPaymentTransactionObserver来返回购买的结果。</p>
<p>我现在拿请求商品信息的部分来举例说明一下：</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">SKProductsRequest<span style="color: #002200;">*</span> req <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>SKProductsRequest alloc<span style="color: #002200;">&#93;</span> initWithProductIdentifiers<span style="color: #002200;">:</span>pids<span style="color: #002200;">&#93;</span>; 
	req.delegate <span style="color: #002200;">=</span> observer;
	<span style="color: #002200;">&#91;</span>req start<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>上面的Objective-C的代码如果转译成ActionScript 3.0，相当于这个意思：</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> req<span style="color: #000066; font-weight: bold;">:</span>SKProductsRequest = SKProductsRequest<span style="color: #000066; font-weight: bold;">.</span>initWithProductIdentifiers<span style="color: #000000;">&#40;</span>pids<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
req<span style="color: #000066; font-weight: bold;">.</span>delegate = observer<span style="color: #000066; font-weight: bold;">;</span>
req<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">start</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>SKProductsRequest继承于父类SKRequest，通过静态方法initWithProductIdentifiers和参数pids创建了一个实例req，参数pids是一个数组，列出了需要请求的内付费商品ID。req通过start方法向商店发出请求，并在发出请求的动作之前给自己注册了一个回调函数observer。</p>
<p>observer是SKProductsRequestDelegate的实例，回调接口如下：</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>productsRequest<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>SKProductsRequest <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>request didReceiveResponse<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>SKProductsResponse <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>response;</pre></div></div>

<p>转译成AS是如下的代码：</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #339966; font-weight: bold;">function</span> productsRequest<span style="color: #000000;">&#40;</span>request<span style="color: #000066; font-weight: bold;">:</span>SKProductsRequest<span style="color: #000066; font-weight: bold;">,</span> response<span style="color: #000066; font-weight: bold;">:</span>SKProductsResponse<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>其中response就是请求的结果。</p>
<p>下面是一个完整的Objective-C函数体：</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>productsRequest<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>SKProductsRequest <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>request didReceiveResponse<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>SKProductsResponse <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>response<span style="color: #002200;">&#123;</span>
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Products Received&quot;</span><span style="color: #002200;">&#41;</span>;
	<span style="color: #400080;">NSMutableString</span><span style="color: #002200;">*</span> retXML <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableString</span> alloc<span style="color: #002200;">&#93;</span> initWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>SKProduct<span style="color: #002200;">*</span> p <span style="color: #a61390;">in</span> response.products<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>retXML appendFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@%@%@%@%@&quot;</span>,p.localizedTitle,p.localizedDescription,p.price,<span style="color: #002200;">&#91;</span>p.priceLocale localeIdentifier<span style="color: #002200;">&#93;</span>,p.productIdentifier<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #002200;">&#91;</span>retXML appendFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">for</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span> s <span style="color: #a61390;">in</span> response.invalidProductIdentifiers<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span> 
		<span style="color: #002200;">&#91;</span>retXML appendFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@&quot;</span>,s<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #002200;">&#91;</span>retXML appendFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;&quot;</span><span style="color: #002200;">&#93;</span>; 
	FREDispatchStatusEventAsync<span style="color: #002200;">&#40;</span>g_ctx, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #bf1d1a;">&quot;productsReceived&quot;</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>retXML UTF8String<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
	<span style="color: #002200;">&#91;</span>retXML release<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>request release<span style="color: #002200;">&#93;</span>; 
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>这里主要实现的是将结果格式化成一个XML流，然后通过派发事件传回给AS扩展类，注意这里派发事件用的是FREDispatchStatusEventAsync方法，它定义在FlashRuntimeExtension.h内部，前文我介绍过，这是负责与AS扩展类通信的类。</p>
<p>在AS类包中，通过注册的StatusEvent来侦听这个事件，并从e.level中取得XML流里的商品信息。</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">ext<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">addEventListener</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">StatusEvent</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">STATUS</span><span style="color: #000066; font-weight: bold;">,</span>onStatus<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000066; font-weight: bold;">...</span>
<span style="color: #339966; font-weight: bold;">function</span> onStatus<span style="color: #000000;">&#40;</span>e<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">StatusEvent</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><span style="color: #000000;">&#123;</span>
     <span style="color: #0033ff; font-weight: bold;">switch</span><span style="color: #000000;">&#40;</span>e<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">code</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#123;</span>
          <span style="color: #0033ff; font-weight: bold;">case</span> <span style="color: #990000;">&quot;productsReceived&quot;</span><span style="color: #000066; font-weight: bold;">:</span>
          <span style="color: #6699cc; font-weight: bold;">var</span> xml<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">XML</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">XML</span><span style="color: #000000;">&#40;</span>e<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">level</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
          <span style="color: #000066; font-weight: bold;">......</span>
     <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>购买的业务流程和请求信息的流程十分相似，这里我不一一介绍，大家可以在最后下载项目的代码来查看。<br />
———————————————————————————<br />
<span style="color: #ff0000;"><strong>ActionScript扩展</strong></span></p>
<p>在Saumitra提供的ANE扩展类中，AS部分的结构是这样的：<br />
com.adobe.nativeExtensions.AppPurchase;<br />
com.adobe.nativeExtensions.AppPurchaseEvent;<br />
com.adobe.nativeExtensions.Base64;<br />
com.adobe.nativeExtensions.Product;<br />
com.adobe.nativeExtensions.Transaction;</p>
<p>其中AppPurchase负责业务流程以及与Native扩展的接口，AppPurchaseEvent定义了各种StatusEvent的状态，Product和Transaction定义了数据模型，Base64负责为参数转码。整个扩展类库简单易懂，我会在下面的项目实例中介绍其中用到的一些方法。<br />
———————————————————————————–<br />
<span style="color: #ff0000;"><strong>ANE－IAP开发实例分享</strong></span></p>
<p>最后总结本系列教程所有的知识来做一个例子。<br />
我首先做的准备是在iTunesConnect中创建了一个新的应用，并新建了四个内付费商品：plane（非消耗型），diary（非消耗型），bottle（消耗型），key（消耗型）。我希望在iPad的沙箱环境中测试以下的业务流程：<br />
请求商品信息，购买消耗型和非消耗性商品，恢复非消耗型商品的购买状态，如果都成功则我的应用调试成功。</p>
<p>分析一下这个应用的UI需求，我需要一个按钮来触发请求商品信息的动作，然后需要一个列表来显示商品信息，接下来需要给每个商品添加一个购买的按钮。由于iPad上无法用trace等debug方法调试，所以我还需要一个监测的窗口来打印所有的流程信息。</p>
<p>下面是该应用的截屏：<br />
<img class="alignnone size-full wp-image-844" title="图2 请求商品列表" src="http://blog-uploads.richmediaplus.com/2011/10/getting-products.jpg" alt="请求商品列表" width="375" height="500" /><br />
图2 请求商品列表<br />
<img class="alignnone size-full wp-image-845" title="图3 显示商品信息" src="http://blog-uploads.richmediaplus.com/2011/10/products-show.jpg" alt="显示商品信息" width="375" height="500" /><br />
图3 显示商品信息<br />
<img class="alignnone size-full wp-image-846" title="图4 恢复非消耗型商品的购买状态" src="http://blog-uploads.richmediaplus.com/2011/10/restore-status.jpg" alt="恢复非消耗型商品的购买状态" width="375" height="239" /><br />
图4 恢复非消耗型商品的购买状态<br />
<img class="alignnone size-full wp-image-847" title="图5 购买新的消耗型商品" src="http://blog-uploads.richmediaplus.com/2011/10/buy-new.jpg" alt="购买新的消耗型商品" width="375" height="500" /><br />
图5 购买新的消耗型商品<br />
<img class="alignnone size-full wp-image-848" title="图6 输入测试用户密码" src="http://blog-uploads.richmediaplus.com/2011/10/test-users.jpg" alt="输入测试用户密码" width="375" height="500" /><br />
图6 输入测试用户密码<br />
<img class="alignnone size-full wp-image-849" title="图7 购买成功" src="http://blog-uploads.richmediaplus.com/2011/10/iap-success.jpg" alt="购买成功" width="375" height="509" /><br />
图7 购买成功</p>
<p><strong>资源：</strong><br />
<a href="http://jamesli.cn/uploads/ANE_IAP.zip">实例ANE-IAP（包括AS扩展类，Native扩展类）下载</a></p>
<p><strong>如何使用本例：</strong><br />
开发者需要使用自己的证书和设备来打包和发布，有关如何打包ANE和如何发布IPA，我已经在这个系列教程的前文提到过了，本文不做重复介绍。</p>
<p><strong>注意事项：</strong><br />
1，本例使用Flash Professional作为Compiler，使用Flash Builder作为代码编辑IDE，请在Flash Professional的发布设置中选择Flash Player，并在发布的时候忽略这个错误： VerifyError: Error #1014: Class flash.external::ExtensionContext could not be found。直接使用生成的SWF即可。</p>
<p>2，在iPad上测试之前务必要先注销已经登陆的苹果帐号，注销方法为，进入系统偏好设置，在左边列表内点击Store图标，然后点击在右侧出现的帐号，再在弹出的窗口中点击”注销“。</p>
<p>3，如果你没有用过XCode，不知道如何发布OBJC项目，请在安装XCode之后打开下载的Native扩展包里的AppPurchase.xcodeproj文件，项目打开后按Command+B，在左边项目资源列表的Products文件夹内会生成一个.a文件，右键点击后可以在Finder中找到这个文件。</p>
<p>总结：<br />
本文所提供的例子，只是应用内付费的入门，如果要做真正的产品，你需要搭建自己的服务器用来验证购买商品的收据，以及在本地记录商品的使用状态并与服务器同步等等。这些知识不是本文的重点，这里不做详细介绍，感兴趣的朋友可以和我做进一步的探讨。谢谢各位！</p>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step2/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程</title>
		<link>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3/</link>
		<comments>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 01:29:32 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[ActionScript3]]></category>
		<category><![CDATA[Air]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash/Flex Mobile Dev]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Dev]]></category>
		<category><![CDATA[Adobe Air]]></category>
		<category><![CDATA[AIR Native Extension]]></category>
		<category><![CDATA[In App Purchase]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=839</guid>
		<description><![CDATA[原文链接： AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程 本文的主要内容如下： IAP简介 商品与交易 测试IAP的准备流程 ———————————————————————————— IAP简介 IAP的全称是In-App Purchase，应用内付费。这种业务模式允许用户免费下载试用，对应用内提供的商品选择消费，比如购买游戏道具，购买游戏等级等等。相比完全收费的应用而言，应用内付费给用户试用的机会，不会让优秀的应用因为缺乏用户的认知而丧失消费者；而且对于开发商，也不需要为了让用户试用而单独发布一款免费的精简版本。 ———————————————————————————— 商品与交易 苹果官方的关于IAP的帮助文档是只对注册开发者开放的，所以我不方便把它转载在这里，但我可以对IAP里的关键因素做一个通俗易懂的介绍。 IAP里有两个关键的词，商品(Product)和交易(Transaction)。 商品可以是一种虚拟的道具，一个隐藏的关卡或者地图，但必须是直观的，可以让用户购买后直接获益的产品。IAP的商品从消费性质上分为四种： 1，消耗型商品，比如游戏道具，子弹，药品等等。由于这类商品可以被消耗，所以支持重复购买。苹果应用商店不保存此类商品的购买记录，如果要保存则需要开发者同步到自己的服务器上。 2，非消耗型商品，比如游戏关卡，隐藏地图等等。这类商品只要购买一次便可以了，苹果应用商店里每一个用户对非消耗型商品的购买都有记录，可以在不同的设备上恢复购买状态，这个恢复的过程叫做Restore。 3，自动重置型订阅，比如电子杂志，读物等。消费者购买这类商品时会从列表中选择一个有效期限，卖家在定义商品的时候从一群固定的选项中选择添加一个有效期，比如7天，一个月，两个月。过了有效期之后，商品的购买状态会被自动重置成未购买，要想继续获得内容则需要再次订阅。这种类型的商品和非消耗型商品一样，会在苹果商店内保存购买记录。 4，非自动重置型订阅，比如用户订阅电子杂志和读物报刊时需要从自定义的期限列表中选择期限，而不是苹果提供的固定选项，比如9天，一个半月或任意时间。在这种情况下，苹果商店无法根据期限来控制订阅的到期行为，所以一切都需要开发商自己编写相应的逻辑来实现。 交易是指用户对一个商品的购买行为，当用户点击购买一件商品时，一个新的付费行为就被添加到付费队列中，付费队列是一条系统线程，即使应用程序终止仍然会继续执行。 ———————————————————————————— 测试IAP的准备流程 如果你是一个注册的苹果开发者，接受了最新的苹果开发者协议，并且签署了iOS付费应用合同，那么你就可以继续IAP的测试了。 如果此时你对iOS的开发流程不是很熟悉，在阅读下面的内容之前，我强烈建议你先看看我的这几篇文章： 如何成为一个合法的iOS开发者 如何使用iOS开发者授权以及如何申请证书 如何为iTunes Connect准备应用 如果你已经注册成为苹果开发者，并且熟知了如何给设备授权，如何申请证书，如何发布应用，那么请继续阅读我下面的内容： 使用未越狱的设备 测试IAP的项目不能使用越狱的设备，否则会出现无法连接到应用商店的错误。恢复设备到未越狱的系统后，登陆Provisioning Portal添加设备的UID。 使用没有通配符的App ID 在定义App的Bundle ID的时候，我曾经介绍过可以使用类似 com.jamesli.* 这样的值来覆盖多个应用的ID。这种定义方式不能用在打算使用IAP的应用上面，定义IAP的应用必须使用唯一的ID，如com.jamesli.ghostbride。如果正确定义了，应用的In-App Purchase的功能是默认开启的，如下图： 在iTunesConnect创建应用 登陆iTunesConnect，创建一个新的应用，即使该应用尚未开发，也可以用一些假的文字和图片来代替，创建好之后切记要点击Ready to Upload binary将应用的状态变为Waiting for upload。 管理In-App Purchase商品 在应用列表中点击新创建的应用图标，进入应用首页，在右面的一行按钮中选择Manage In-App Purchase，进入内付费商品管理页面。通过点击左上角的Create New按钮可以进入商品页面选择创建一个新的商品。页面中显示的四种商品分别是我在本文介绍过的四种商品，消耗型商品（Consumable），非消耗型商品（Non-Consumable），自动重置型订阅（Auto-Renewable [...]
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>原文链接：<br />
<a title="Permanent Link to AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程" href="http://jamesli.cn/blog/?p=1174" rel="bookmark">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程</a></p>
<p><strong>本文的主要内容如下：</strong></p>
<ul>
<li>IAP简介</li>
<li>商品与交易</li>
<li>测试IAP的准备流程</li>
</ul>
<p>————————————————————————————<br />
<span style="color: #ff0000;"><strong>IAP简介</strong></span></p>
<p>IAP的全称是In-App Purchase，应用内付费。这种业务模式允许用户免费下载试用，对应用内提供的商品选择消费，比如购买游戏道具，购买游戏等级等等。相比完全收费的应用而言，应用内付费给用户试用的机会，不会让优秀的应用因为缺乏用户的认知而丧失消费者；而且对于开发商，也不需要为了让用户试用而单独发布一款免费的精简版本。</p>
<p>————————————————————————————<br />
<span style="color: #ff0000;"><strong>商品与交易</strong></span></p>
<p>苹果官方的关于IAP的帮助文档是只对注册开发者开放的，所以我不方便把它转载在这里，但我可以对IAP里的关键因素做一个通俗易懂的介绍。</p>
<p>IAP里有两个关键的词，商品(Product)和交易(Transaction)。<br />
商品可以是一种虚拟的道具，一个隐藏的关卡或者地图，但必须是直观的，可以让用户购买后直接获益的产品。IAP的商品从消费性质上分为四种：</p>
<p>1，<strong>消耗型商品</strong>，比如游戏道具，子弹，药品等等。由于这类商品可以被消耗，所以支持重复购买。苹果应用商店不保存此类商品的购买记录，如果要保存则需要开发者同步到自己的服务器上。</p>
<p>2，<strong>非消耗型商品</strong>，比如游戏关卡，隐藏地图等等。这类商品只要购买一次便可以了，苹果应用商店里每一个用户对非消耗型商品的购买都有记录，可以在不同的设备上恢复购买状态，这个恢复的过程叫做Restore。</p>
<p>3，<strong>自动重置型订阅</strong>，比如电子杂志，读物等。消费者购买这类商品时会从列表中选择一个有效期限，卖家在定义商品的时候从一群固定的选项中选择添加一个有效期，比如7天，一个月，两个月。过了有效期之后，商品的购买状态会被自动重置成未购买，要想继续获得内容则需要再次订阅。这种类型的商品和非消耗型商品一样，会在苹果商店内保存购买记录。</p>
<p>4，<strong>非自动重置型订阅</strong>，比如用户订阅电子杂志和读物报刊时需要从自定义的期限列表中选择期限，而不是苹果提供的固定选项，比如9天，一个半月或任意时间。在这种情况下，苹果商店无法根据期限来控制订阅的到期行为，所以一切都需要开发商自己编写相应的逻辑来实现。</p>
<p>交易是指用户对一个商品的购买行为，当用户点击购买一件商品时，一个新的付费行为就被添加到付费队列中，付费队列是一条系统线程，即使应用程序终止仍然会继续执行。</p>
<p>————————————————————————————<br />
<span style="color: #ff0000;"><strong>测试IAP的准备流程</strong></span></p>
<p><strong>如果你是一个注册的苹果开发者，接受了最新的苹果开发者协议，并且签署了iOS付费应用合同，那么你就可以继续IAP的测试了。</strong></p>
<p>如果此时你对iOS的开发流程不是很熟悉，在阅读下面的内容之前，我强烈建议你先看看我的这几篇文章：<br />
<a href="http://jamesli.cn/blog/?p=966" target="_blank">如何成为一个合法的iOS开发者</a><br />
<a href="http://jamesli.cn/blog/?p=995" target="_blank">如何使用iOS开发者授权以及如何申请证书</a><br />
<a href="http://jamesli.cn/blog/?p=1045" target="_blank">如何为iTunes Connect准备应用</a></p>
<p>如果你已经注册成为苹果开发者，并且熟知了如何给设备授权，如何申请证书，如何发布应用，那么请继续阅读我下面的内容：</p>
<p><strong>使用未越狱的设备</strong><br />
测试IAP的项目不能使用越狱的设备，否则会出现无法连接到应用商店的错误。恢复设备到未越狱的系统后，登陆<a href="http://developer.apple.com/ios/manage/overview/index.action">Provisioning Portal</a>添加设备的UID。</p>
<p><strong>使用没有通配符的App ID</strong><br />
在定义App的Bundle ID的时候，我曾经介绍过可以使用类似 com.jamesli.* 这样的值来覆盖多个应用的ID。这种定义方式不能用在打算使用IAP的应用上面，定义IAP的应用必须使用唯一的ID，如com.jamesli.ghostbride。如果正确定义了，应用的In-App Purchase的功能是默认开启的，如下图：<br />
<img src="http://blog-uploads.richmediaplus.com/2011/10/app-bundle-id-e1318038302389.jpg" alt="" title="app-bundle-id" width="500" height="171" class="alignnone size-full wp-image-841" /></p>
<p><strong>在iTunesConnect创建应用</strong><br />
登陆<a href="http://itunesconnect.apple.com/" target="_blank">iTunesConnect</a>，创建一个新的应用，即使该应用尚未开发，也可以用一些假的文字和图片来代替，<strong>创建好之后切记要点击Ready to Upload binary将应用的状态变为Waiting for upload。</strong></p>
<p><strong>管理In-App Purchase商品</strong><br />
在应用列表中点击新创建的应用图标，进入应用首页，在右面的一行按钮中选择Manage In-App Purchase，进入内付费商品管理页面。通过点击左上角的Create New按钮可以进入商品页面选择创建一个新的商品。页面中显示的四种商品分别是我在本文介绍过的四种商品，消耗型商品（Consumable），非消耗型商品（Non-Consumable），自动重置型订阅（Auto-Renewable Subscriptions），非自动重置型订阅（Non-Renewing Subscription）。</p>
<p>以消耗型商品为例，点击Select进入创建页面。<br />
Reference Name是商品名字，这不是最终用户会看到的名字，而是会在内付费管理的商品列表中显示的字符，类似于变量名。<br />
Product ID是商品的唯一标识，这个ID十分重要，在编写应用程序的时候会用它来识别改商品。</p>
<p>接下来是为不同的语言定义该商品的显示名称，最终用户看到的就是这个名称。定义好名称后是为商品定价以及上传缩略图，这个商品就算是定义完了。如下图，定义完成的商品会显示在内付费管理的商品列表中。每一个内付费商品的创建和修改都需要提交审核，但这里需要注意的是，<strong>在一个新的应用版本内创建的内付费商品，必须和这个应用版本一起提交审核，而在该应用版本通过审核之后再为它创建的内付费商品，可以通过这个列表中的Ready to submit按钮来提交。</strong><br />
<img src="http://blog-uploads.richmediaplus.com/2011/10/product-iap-e1318038419260.png" alt="product-iap" title="product-iap" width="500" height="95" class="alignnone size-full wp-image-842" /></p>
<p>刚刚创建好的内付费应用，已经可以用来调试了。</p>
<p><strong>使用测试帐号调试应用</strong></p>
<p>苹果应用商店是一个交易环境，任何用户可以在这个环境内购买应用，但如果要测试正在开发过程中的应用内付费，我们不能在真正的苹果商店里进行。苹果给开发者提供了一个用于调试购买行为的测试沙箱，它完全复制了应用商店的交易环境，但在沙箱环境中我们不能用平常的苹果帐号，而是需要用测试帐号。</p>
<p>在iTunesConnect的首页可以点击Manage Users进入用户管理页面，然后选择Test User来创建测试帐号。创建测试帐号可以使用一个不存在的Email地址，但是密码必须是符合规范的。这里创建的帐号可以用来购买开发过程中的应用内付费，<strong>但必须记住，测试帐号不能用来登陆真正的应用商店并在产品环境中进行购买行为，否则你的iTunes帐号将有可能被停用。</strong></p>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展</title>
		<link>http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step2/</link>
		<comments>http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step2/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 14:41:10 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[ActionScript3]]></category>
		<category><![CDATA[Air]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash/Flex Mobile Dev]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Dev]]></category>
		<category><![CDATA[Adobe Air]]></category>
		<category><![CDATA[AIR Native Extension]]></category>
		<category><![CDATA[In App Purchase]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=833</guid>
		<description><![CDATA[原文链接： AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展 本文的主要内容如下 AIR Native Extension介绍 ANE的组成部分 ActionScript 3.0扩展 Objective-C 扩展 使用ADT打包ANE 使用ADT打包IPA ———————————————————————————— AIR Native Extension介绍 AIR Native Extension (ANE)是AIR 3.0的一项重要特性，简单的说，它允许AIR应用程序通过扩展文件与原生应用程序类库相互通讯，从而让AIR应用实现一些只有原生程序才可以做到的功能。 在ANE出现以前，移动平台上的AIR对系统的访问非常有限，功能的实现都是封装在封闭的，由Adobe定义好的ActionScript 3.0 API内，比如Accelerometer, GeoLocator等AS类。ANE则将AIR彻底开放出来，AIR不再针对具体的功能提供封闭的API，而是允许开发者通过AIR的扩展机制自由调用使用原生语言开发的类库。这样可以让AIR应用程序享有与原生应用程序同等的机会，其意义对Flash技术来说是划时代的。 ———————————————————————————— ANE的组成部分 ANE支持向Windows、Mac OSX、Android和iOS各个平台原生应用程序的扩展，本文只针对iOS平台进行介绍。在iOS平台中，ANE的组成部分基本分为ActionScript 3.0扩展类库和Objective-C原生扩展类库两个部分，这两个部分打包后生成AIR扩展文件(.ane)，最后和AIR应用程序一起打包成iOS原生应用IPA文件。如下图所示。 图1 ANE的组成部分 ———————————————————————————— ActionScript 3.0扩展 ANE的AS扩展部分是一个SWC，AIR 3.0 SDK里为flash.external.ExtensionContext类添加了新的方法。如下例所示： import flash.external.ExtensionContext; ... private var ext:ExtensionContext; ... ext = ExtensionContext.createExtensionContext&#40;&#34;com.adobe.appPurchase&#34;,&#34;&#34;&#41;; 在这个例子里，ExtensionContext通过静态方法createExtensionContext()来获得一个实例，参数com.adobe.appPurchase是这个扩展的ID，它非常重要，在扩展的配置文件里和应用程序描述文件中都需要用这个ID进行配对。 调用原生类中定义的方法可以用方法call()来实现，由于是同步调用，所以函数可以有返回值。如在原生类中定义的方法finish，可以用下面的代码来调用。 var [...]
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>原文链接：<br />
<a title="Permanent Link to AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展" href="http://jamesli.cn/blog/?p=1164" rel="bookmark">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展</a></p>
<p><strong>本文的主要内容如下</strong></p>
<ul>
<li>AIR Native Extension介绍</li>
<li>ANE的组成部分</li>
<li>ActionScript 3.0扩展</li>
<li>Objective-C 扩展</li>
<li>使用ADT打包ANE</li>
<li>使用ADT打包IPA</li>
</ul>
<p>————————————————————————————<br />
<span style="color: #ff0000;"><strong>AIR Native Extension介绍</strong></span></p>
<p>AIR Native Extension (ANE)是AIR 3.0的一项重要特性，简单的说，它允许AIR应用程序通过扩展文件与原生应用程序类库相互通讯，从而让AIR应用实现一些只有原生程序才可以做到的功能。<br />
在ANE出现以前，移动平台上的AIR对系统的访问非常有限，功能的实现都是封装在封闭的，由Adobe定义好的ActionScript 3.0 API内，比如Accelerometer, GeoLocator等AS类。ANE则将AIR彻底开放出来，AIR不再针对具体的功能提供封闭的API，而是允许开发者通过AIR的扩展机制自由调用使用原生语言开发的类库。这样可以让AIR应用程序享有与原生应用程序同等的机会，其意义对Flash技术来说是划时代的。<br />
————————————————————————————<br />
<span style="color: #ff0000;"><strong>ANE的组成部分</strong></span></p>
<p>ANE支持向Windows、Mac OSX、Android和iOS各个平台原生应用程序的扩展，本文只针对iOS平台进行介绍。在iOS平台中，ANE的组成部分基本分为ActionScript 3.0扩展类库和Objective-C原生扩展类库两个部分，这两个部分打包后生成AIR扩展文件(.ane)，最后和AIR应用程序一起打包成iOS原生应用IPA文件。如下图所示。</p>
<p><img class="alignnone size-full wp-image-834" title="图1 ANE的组成部分" src="http://blog-uploads.richmediaplus.com/2011/10/ane-construction.png" alt="ANE的组成部分" width="465" height="289" /></p>
<p>图1 ANE的组成部分<br />
————————————————————————————<br />
<span style="color: #ff0000;"><strong>ActionScript 3.0扩展</strong></span></p>
<p>ANE的AS扩展部分是一个SWC，AIR 3.0 SDK里为flash.external.ExtensionContext类添加了新的方法。如下例所示：</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.external</span><span style="color: #000066; font-weight: bold;">.</span>ExtensionContext<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000066; font-weight: bold;">...</span>
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #6699cc; font-weight: bold;">var</span> ext<span style="color: #000066; font-weight: bold;">:</span>ExtensionContext<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000066; font-weight: bold;">...</span>
ext = ExtensionContext<span style="color: #000066; font-weight: bold;">.</span>createExtensionContext<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;com.adobe.appPurchase&quot;</span><span style="color: #000066; font-weight: bold;">,</span><span style="color: #990000;">&quot;&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>在这个例子里，ExtensionContext通过静态方法createExtensionContext()来获得一个实例，<strong>参数com.adobe.appPurchase是这个扩展的ID，它非常重要，在扩展的配置文件里和应用程序描述文件中都需要用这个ID进行配对。</strong></p>
<p>调用原生类中定义的方法可以用方法call()来实现，由于是同步调用，所以函数可以有返回值。如在原生类中定义的方法finish，可以用下面的代码来调用。</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> result<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Object</span> = ext<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">call</span><span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;finish&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>我们还可以给ExtensionContext类添加事件侦听，用来获取从原生类中派发回来的事件。</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">ext<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">addEventListener</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">StatusEvent</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">STATUS</span><span style="color: #000066; font-weight: bold;">,</span>onStatus<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> onStatus<span style="color: #000000;">&#40;</span>e<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">StatusEvent</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><span style="color: #000000;">&#123;</span> 
	<span style="color: #0033ff; font-weight: bold;">switch</span><span style="color: #000000;">&#40;</span>e<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">code</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#123;</span>
             <span style="color: #0033ff; font-weight: bold;">case</span> <span style="color: #990000;">&quot;removeTransaction&quot;</span><span style="color: #000066; font-weight: bold;">:</span>
             <span style="color: #000066; font-weight: bold;">...</span>
        <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>————————————————————————————<br />
<span style="color: #ff0000;"><strong>Objective-C 扩展</strong></span><br />
接下来是原生类的部分，如果你注册成为苹果iOS开发者，那么你可以在<a href="http://developer.apple.com/devcenter/ios/index.action" target="_blank">苹果开发者网站</a>上免费下载Object-C的开发工具XCode。关于如何注册成为苹果iOS开发者，请参考我的这篇文章，<a href="http://jamesli.cn/blog/?p=966" target="_blank">如何成为一个合法的iOS开发者</a>。</p>
<p>总的来说，Objective-C 虽然语法比较奇怪，但只要掌握了基本的规则，还是和ActionScript一样易懂。OBJC扩展类需要引入一个FlashRuntimeExtension.h类包，它实现了和ActionScript沟通的接口。</p>
<p>引入FlashRuntimeExtension.h之后，可以用下面的代码定义一个FREObject方法，FREObject是接口类型。<strong>这里要注意，与AS的接口包括函数返回值，都要定义成FREObject类型</strong>，比如代码中的retVal。</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">FREObject finishTransaction1<span style="color: #002200;">&#40;</span>FREContext ctx, <span style="color: #a61390;">void</span><span style="color: #002200;">*</span> funcData, uint32_t argc, FREObject argv<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Finish Transaction Called&quot;</span><span style="color: #002200;">&#41;</span>;
	<span style="color: #a61390;">BOOL</span> matchFound <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;
	<span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span> str <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
	uint32_t len <span style="color: #002200;">=</span> <span style="color: #002200;">-</span><span style="color: #2400d9;">1</span>;
	......
	FREObject retVal;
	<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>FRENewObjectFromBool<span style="color: #002200;">&#40;</span>matchFound, <span style="color: #002200;">&amp;</span>amp;retVal<span style="color: #002200;">&#41;</span> <span style="color: #002200;">==</span> FRE_OK<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#123;</span>
		<span style="color: #a61390;">return</span> retVal;
	<span style="color: #002200;">&#125;</span><span style="color: #a61390;">else</span><span style="color: #002200;">&#123;</span>
		<span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
	<span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>要把FREObject方法定义成接口，还需要在ContextInitializer方法内进行配置，如下：</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">//这里是需要定义的接口的数量</span>
<span style="color: #002200;">*</span>numFunctionsToTest <span style="color: #002200;">=</span> <span style="color: #2400d9;">6</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">//定义一个FRENamedFunction类型的实例func，初始化函数的个数</span>
FRENamedFunction<span style="color: #002200;">*</span> func <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>FRENamedFunction<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #a61390;">malloc</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>FRENamedFunction<span style="color: #002200;">&#41;</span><span style="color: #002200;">*</span><span style="color: #2400d9;">6</span><span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">//定义一个接口，name是字符串&quot;getProducts&quot;，函数体是getProducts</span>
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>.name <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #bf1d1a;">&quot;getProducts&quot;</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>.functionData <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#93;</span>.function <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;getProducts; 
&nbsp;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>.name <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #bf1d1a;">&quot;startPayment&quot;</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>.functionData <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span>.function <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;startAppPayment; 
&nbsp;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span>.name <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #bf1d1a;">&quot;finish&quot;</span>; 
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span>.functionData <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span>.function <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;finishTransaction1;
&nbsp;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">3</span><span style="color: #002200;">&#93;</span>.name <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #bf1d1a;">&quot;muted&quot;</span>; 
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">3</span><span style="color: #002200;">&#93;</span>.functionData <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">3</span><span style="color: #002200;">&#93;</span>.function <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;muted;
&nbsp;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">4</span><span style="color: #002200;">&#93;</span>.name <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #bf1d1a;">&quot;restore&quot;</span>; 
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">4</span><span style="color: #002200;">&#93;</span>.functionData <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">4</span><span style="color: #002200;">&#93;</span>.function <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;restoreTrans;
&nbsp;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">5</span><span style="color: #002200;">&#93;</span>.name <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> uint8_t<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #bf1d1a;">&quot;trans&quot;</span>; 
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">5</span><span style="color: #002200;">&#93;</span>.functionData <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
func<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">5</span><span style="color: #002200;">&#93;</span>.function <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;getTrans;
&nbsp;
<span style="color: #002200;">*</span>functionsToSet <span style="color: #002200;">=</span> func;
....</pre></div></div>

<p>而ContextInitializer方法，是在原生扩展类的初始化函数ExtInitializer中指定的：</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">void</span> ExtInitializer<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">**</span> extDataToSet, FREContextInitializer<span style="color: #002200;">*</span> ctxInitializerToSet, 
					FREContextFinalizer<span style="color: #002200;">*</span> ctxFinalizerToSet<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Extension Initialized&quot;</span><span style="color: #002200;">&#41;</span>;
	<span style="color: #002200;">*</span>extDataToSet <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
	<span style="color: #002200;">*</span>ctxInitializerToSet <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;ContextInitializer;
	<span style="color: #002200;">*</span>ctxFinalizerToSet <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>amp;ContextFinalizer;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>ExtInitializer是原生扩展的程序入口，它可以通过扩展配置文件extension.xml来定义：</p>
<pre>&lt;?xml version="1.0" encoding="utf-8" standalone="yes"?&gt;
&lt;extension xmlns="http://ns.adobe.com/air/extension/2.5"&gt;
  &lt;id&gt;com.adobe.appPurchase&lt;/id&gt;
  &lt;versionNumber&gt;1&lt;/versionNumber&gt;
  &lt;platforms&gt;
    &lt;platform name="iPhone-ARM"&gt;
            &lt;applicationDeployment&gt;
                &lt;nativeLibrary&gt;libAppPurchase.a&lt;/nativeLibrary&gt;
                &lt;initializer&gt;ExtInitializer&lt;/initializer&gt;
                &lt;finalizer&gt;ExtFinalizer&lt;/finalizer&gt;
            &lt;/applicationDeployment&gt;
        &lt;/platform&gt;
  &lt;/platforms&gt;
&lt;/extension&gt;</pre>
<p>我介绍的这个顺序，实际上就是实际程序编写的思路，先确定接口，再实现连接。 也许有朋友和我一开始接触OBJC的时候一样，对这些代码一头雾水。没有关系，在这篇教程里我只是对流程做简短的介绍，具体的代码解析会在本系列的最后一篇教程里做更详细的讲解。那么接下来让我来介绍下一个部分，打包扩展。<br />
————————————————————————————<br />
<span style="color: #ff0000;"><strong>使用ADT打包ANE</strong></span></p>
<p>在图1中，我介绍了.ane文件的组成，它包括了AS类库(.swc)和原生类(.a)两个部分，以及刚才我们介绍的这个扩展配置文件extension.xml。那么要打包ane我们还需要哪些文件呢？<br />
<img class="alignnone size-full wp-image-835" title="图2 打包ANE所需要的文件" src="http://blog-uploads.richmediaplus.com/2011/10/ane-files.png" alt="打包ANE所需要的文件" width="322" height="379" /><br />
图2 打包ANE所需要的文件</p>
<p>如图2所示，所选择的文件以及文件夹就是打包ANE所需要的所有文件，它包括：<br />
1，AIR SDK打包应用程序和类库(bin,lib)<br />
2，ActionScript扩展类包.swc，如图ANE_IAP_ASLib.swc<br />
3，ActionScript扩展类包.swf，如图library.swf，可以通过将SWC的文件扩展名改成ZIP后解压缩得到。<br />
4，Objective-C扩展类包.a，如图libAppPurchase.a，可以通过在Xcode中编译项目得到。<br />
5，扩展配置文件XML，如图extension.xml<br />
6，一个打包证书，如图selfsigned.p12，可以通过Flash CS5的AIR发布设置生成。</p>
<p>一切就绪后便可以使用命令行进行打包，注意路径，下例路径为当前文件夹。</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">bin<span style="color: #000000; font-weight: bold;">/</span>adt <span style="color: #660033;">-package</span> <span style="color: #660033;">-storetype</span> pkcs12 <span style="color: #660033;">-keystore</span> selfsigned.p12 <span style="color: #660033;">-storepass</span> <span style="color: #000000;">1234</span> <span style="color: #660033;">-target</span> ane ext<span style="color: #000000; font-weight: bold;">/</span>InApp.ane extension.xml <span style="color: #660033;">-swc</span> ANE_IAP_ASLib.swc <span style="color: #660033;">-platform</span> iPhone-ARM library.swf libAppPurchase.a</pre></div></div>

<p>————————————————————————————<br />
<span style="color: #ff0000;"><strong>使用ADT打包IPA</strong></span></p>
<p>.ane文件打包成功后，便可以用来打包IPA文件，也就是iOS应用程序包。如果你对开发iOS应用的必要流程还不很清楚，请参阅我的这篇教程，<a href="http://jamesli.cn/blog/?p=995" target="_blank">如何使用iOS开发者授权以及如何申请证书</a>。我以前介绍过如何用Flash Professional CS5打包IPA，今天主要介绍如何用AIR SDK的打包工具ADT来生成含有ANE扩展的IPA。</p>
<p><img class="alignnone size-full wp-image-836" title="图3 使用ADT生成含有ANE扩展的IPA所需要的文件" src="http://blog-uploads.richmediaplus.com/2011/10/adt-ane-ipa-files.png" alt="使用ADT生成含有ANE扩展的IPA所需要的文件" width="323" height="391" /><br />
图3 使用ADT生成含有ANE扩展的IPA所需要的文件</p>
<p>如图3所示，所选择的文件就是生成IPA的必要文件：<br />
1，应用程序文件SWF，如图是ANE_IAP_Example.swf。<br />
2，开发者设备授权文件.mobileprovision，如图是ghostbride_dev.mobileprovision。<br />
3，开发者签名证书文件.p12，如图是jameslidevelopment.p12。<br />
4，应用程序描述文件XML，如图是info-app.xml。<br />
5，扩展包路径，如图是ext<br />
6，如果应用程序有图标图片，还需要图标文件夹，如图是icon</p>
<p>在应用描述文件XML中，需要对扩展追加一个定义：</p>
<pre>&lt;extensions&gt;
    &lt;extensionID&gt;com.adobe.appPurchase&lt;/extensionID&gt;
&lt;/extensions&gt;</pre>
<p>这里可以看到，在AS扩展类、扩展配置文件extension.xml和应用描述文件info-app.xml中都指定了一个统一扩展的ID: com.adobe.appPurchase。</p>
<p>利用下面的命令行可以打包生成Main.ipa:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">bin<span style="color: #000000; font-weight: bold;">/</span>adt <span style="color: #660033;">-package</span> <span style="color: #660033;">-target</span> ipa-test-interpreter <span style="color: #660033;">-provisioning-profile</span> ghostbride_dev.mobileprovision <span style="color: #660033;">-storetype</span> pkcs12 <span style="color: #660033;">-keystore</span> jameslidevelopment.p12 <span style="color: #660033;">-storepass</span> <span style="color: #000000;">1234</span> Main.ipa info-app.xml ANE_IAP_Example.swf <span style="color: #660033;">-extdir</span> ext icon</pre></div></div>

<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</title>
		<link>http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/</link>
		<comments>http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 14:10:04 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[ActionScript3]]></category>
		<category><![CDATA[Air]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash/Flex Mobile Dev]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Dev]]></category>
		<category><![CDATA[Adobe Air]]></category>
		<category><![CDATA[AIR Native Extension]]></category>
		<category><![CDATA[In App Purchase]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=831</guid>
		<description><![CDATA[原文链接： AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览 阅读本文的基础 ActionScript 3.0编程基础 Apple iOS开发者权限 前言 记得在写Flash开发iOS应用全攻略的时候，不少感兴趣的朋友询问Flash技术是否能实现App Store的应用内付费功能（In-App Purchase，以下简称IAP）。在那个时候我只能说，很抱歉，目前还不支持，但是在半年后的今天，在我提笔写这篇教程的时候，我刚刚完成了一个用Flash技术实现IAP的例子。确切的说，是用AIR 3.0的原生扩展功能（AIR Native Extension，以下简称ANE）实现的。ANE作为AIR 3.0的一项重要特性，为Flash平台往系统底层的功能延伸奠定了基础，为Flash开发者在移动设备上开发商业应用提供了技术保证。它的出现，使AIR更具开放性，随即推动的是使用AIR和原生技术共同开发工作流，AS开发者与Native开发者的关系也将从以往的竞争转为合作。 在这个系列的文章中，我会对ANE做一个详细的介绍，同样介绍的还有苹果IAP的相关知识，最后通过一个具体的例子来讲解从流程到代码，从思路到技巧等各方面的知识点。希望各位朋友在阅读之后可以全面掌握ANE和IAP，并在实际的应用开发中派上用场。 内容提要 本系列文章大概内容如下： AIR面向iOS设备的原生扩展 AIR Native Extension介绍 ANE的组成部分 ActionScript 3.0扩展 Objective-C 扩展 使用ADT打包ANE 使用ADT打包IPA iOS应用内付费的实现原理和准备流程 IAP简介 商品与交易 测试IAP的准备流程 ANE面向IAP的测试和开发 在Native扩展中使用StoreKit框架 ActionScript扩展 ANE－IAP开发实例分享 Related posts: AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程 AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展 AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step2/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>原文链接：<br />
<a title="Permanent Link to AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览" href="http://jamesli.cn/blog/?p=1152" rel="bookmark">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></p>
<p><strong>阅读本文的基础</strong><br />
ActionScript 3.0编程基础<br />
Apple iOS开发者权限</p>
<p><strong>前言</strong><br />
记得在写Flash开发iOS应用全攻略的时候，不少感兴趣的朋友询问Flash技术是否能实现App Store的应用内付费功能（In-App Purchase，以下简称IAP）。在那个时候我只能说，很抱歉，目前还不支持，但是在半年后的今天，在我提笔写这篇教程的时候，我刚刚完成了一个用Flash技术实现IAP的例子。确切的说，是用AIR 3.0的原生扩展功能（AIR Native Extension，以下简称ANE）实现的。ANE作为AIR 3.0的一项重要特性，为Flash平台往系统底层的功能延伸奠定了基础，为Flash开发者在移动设备上开发商业应用提供了技术保证。它的出现，使AIR更具开放性，随即推动的是使用AIR和原生技术共同开发工作流，AS开发者与Native开发者的关系也将从以往的竞争转为合作。</p>
<p>在这个系列的文章中，我会对ANE做一个详细的介绍，同样介绍的还有苹果IAP的相关知识，最后通过一个具体的例子来讲解从流程到代码，从思路到技巧等各方面的知识点。希望各位朋友在阅读之后可以全面掌握ANE和IAP，并在实际的应用开发中派上用场。</p>
<p><strong>内容提要</strong><br />
本系列文章大概内容如下：</p>
<p><a href="http://jamesli.cn/blog/?p=1164" target="_blank"><strong>AIR面向iOS设备的原生扩展</strong></a><br />
AIR Native Extension介绍<br />
ANE的组成部分<br />
ActionScript 3.0扩展<br />
Objective-C 扩展<br />
使用ADT打包ANE<br />
使用ADT打包IPA</p>
<p><a href="http://jamesli.cn/blog/?p=1174" target="_blank"><strong>iOS应用内付费的实现原理和准备流程</strong></a><br />
IAP简介<br />
商品与交易<br />
测试IAP的准备流程</p>
<p><a href="http://jamesli.cn/blog/?p=1179" target="_blank"><strong>ANE面向IAP的测试和开发</strong></a><br />
在Native扩展中使用StoreKit框架<br />
ActionScript扩展<br />
ANE－IAP开发实例分享</p>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step2/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程</title>
		<link>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/</link>
		<comments>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 14:00:01 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[ActionScript3]]></category>
		<category><![CDATA[Air]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash/Flex Mobile Dev]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Dev]]></category>
		<category><![CDATA[Adobe Air]]></category>
		<category><![CDATA[AIR Native Extension]]></category>
		<category><![CDATA[In App Purchase]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=832</guid>
		<description><![CDATA[前段一大部分的时间是在研究Adobe AIR Native Extension实现iOS应用内付费(In-App Purchase)，并且在 Adobe 的 James Li 的帮助下测试成功。 现在 Adobe 的 James Li 已经完成了关于 AIR Native Extension实现iOS应用内付费(In-App Purchase) 的全教程。 下面为从 Adobe 的 James Li 转载过来的原稿。 AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览 AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展 AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程 AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发 Related posts: AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览 AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程 AIR Native [...]
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>前段一大部分的时间是在研究Adobe AIR Native Extension实现iOS应用内付费(In-App Purchase)，并且在 Adobe 的 <a href="http://www.jamesli.cn/blog/" target="_blank">James Li</a> 的帮助下测试成功。<br />
现在 Adobe 的 James Li 已经完成了关于 AIR Native Extension实现iOS应用内付费(In-App Purchase) 的全教程。<br />
下面为从 Adobe 的 James Li 转载过来的原稿。</p>
<ul>
<li><a href="http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step1" target="_blank">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
<li><a href="http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step2" target="_blank">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（二）——AIR面向iOS设备的原生扩展</a></li>
<li><a href="http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3" target="_blank">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程</a></li>
<li><a href="http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4" target="_blank">AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></li>
</ul>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/10/air-native-extension-ios-in-app-purchase-step1/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（一）——概览</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step3/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（三）——iOS应用内付费简介和准备流程</a></li>
<li><a href='http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase-step4/' rel='bookmark' title='AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发'>AIR Native Extension实现iOS应用内付费(In-App Purchase)全教程（四）——ANE面向IAP的测试和开发</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2011/10/adobe-air-native-extension-ios-in-app-purchase/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash Player 10.1 and AIR 2 正式版放出</title>
		<link>http://blog.richmediaplus.com/2010/06/flash-player-10-1-and-air-2-released/</link>
		<comments>http://blog.richmediaplus.com/2010/06/flash-player-10-1-and-air-2-released/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 06:50:47 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Adobe Air]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=587</guid>
		<description><![CDATA[﻿Flash Player 10.1 and AIR 2 正式版已经放出。 前面下载过Flash Player 10.1 Beta的要先用最新的uninstall_flash_player (226 KB) (updated 06/10/2010)卸载，并且先重启删除原有文件后安装。 Flash Player 10.1 继续在性能和功耗管理、视频等方面进行了完善，并且支持多点触控和隐私浏览。除了修复众多bug，继续多麦克风直接输入使用进行完善，还能配合 Adobe Flash Access 进行内容保护，在多任务下能够及时控制CPU使用和Flash Player自身的frame rate以此来改进性能。 Flash Player 10.1 features AIR 2.0 支持多点触摸，支持通过AIR直接用系统默认程序打开文件，支持了TLS/SSL socket 通信，更新Webkit支持HTML5/CSS3（应该支持蛮少的，记得是同Safari 4.0.3的内核，人家都已经奔Safari 5啦，Webkit永远跟不上人家，就算跟得上，能力也有限，这一点是让人非常不爽之处） AIR 2.0 features 下载 Flash Player 10.1 正式版 下载 Flash Player 10.1 Debugger 正式版 下载 AIR 2.0 正式版 Related [...]
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/09/nested-mask-crash-issue/' rel='bookmark' title='巢狀遮罩造成 Flash Player 死機的 Bug'>巢狀遮罩造成 Flash Player 死機的 Bug</a></li>
<li><a href='http://blog.richmediaplus.com/2011/09/fp-102-103-textfield-font-issue/' rel='bookmark' title='Flash Player 10.2, 10.3 TextField 中文字體問題'>Flash Player 10.2, 10.3 TextField 中文字體問題</a></li>
<li><a href='http://blog.richmediaplus.com/2011/08/update-flash-ide-auth-player/' rel='bookmark' title='如何更新 Flash CS5.5 內建除錯 Player'>如何更新 Flash CS5.5 內建除錯 Player</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>﻿Flash Player 10.1 and AIR 2 正式版已经放出。</p>
<p>前面下载过Flash Player 10.1 Beta的要先用最新的<a href="http://download.macromedia.com/pub/flashplayer/current/uninstall_flash_player.exe" target="_blank">uninstall_flash_player</a> (226 KB) (updated 06/10/2010)卸载，并且先重启删除原有文件后安装。</p>
<p>Flash Player 10.1 继续在性能和功耗管理、视频等方面进行了完善，并且支持多点触控和隐私浏览。除了修复众多bug，继续多麦克风直接输入使用进行完善，还能配合 Adobe Flash Access 进行内容保护，在多任务下能够及时控制CPU使用和Flash Player自身的frame rate以此来改进性能。<br />
<a href="http://www.adobe.com/products/flashplayer/features/" target="_blank">Flash Player 10.1 features</a></p>
<p>AIR 2.0 支持多点触摸，支持通过AIR直接用系统默认程序打开文件，支持了TLS/SSL socket 通信，更新Webkit支持HTML5/CSS3（应该支持蛮少的，记得是同Safari 4.0.3的内核，人家都已经奔Safari 5啦，Webkit永远跟不上人家，就算跟得上，能力也有限，这一点是让人非常不爽之处）<br />
<a href="http://www.adobe.com/products/air/features/" target="_blank">AIR 2.0 features</a></p>
<ul>
<li><a href="http://www.adobe.com/go/getflashplayer" target="_blank">下载 Flash Player 10.1 正式版</a></li>
<li><a href="http://www.adobe.com/support/flashplayer/downloads.html" target="_blank">下载 Flash Player  10.1 Debugger 正式版</a></li>
<li><a href="http://www.adobe.com/go/getair" target="_blank">下载 AIR 2.0 正式版</a></li>
</ul>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2011/09/nested-mask-crash-issue/' rel='bookmark' title='巢狀遮罩造成 Flash Player 死機的 Bug'>巢狀遮罩造成 Flash Player 死機的 Bug</a></li>
<li><a href='http://blog.richmediaplus.com/2011/09/fp-102-103-textfield-font-issue/' rel='bookmark' title='Flash Player 10.2, 10.3 TextField 中文字體問題'>Flash Player 10.2, 10.3 TextField 中文字體問題</a></li>
<li><a href='http://blog.richmediaplus.com/2011/08/update-flash-ide-auth-player/' rel='bookmark' title='如何更新 Flash CS5.5 內建除錯 Player'>如何更新 Flash CS5.5 內建除錯 Player</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2010/06/flash-player-10-1-and-air-2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe AIR 2 rc released</title>
		<link>http://blog.richmediaplus.com/2010/05/adobe-air-2-rc-released/</link>
		<comments>http://blog.richmediaplus.com/2010/05/adobe-air-2-rc-released/#comments</comments>
		<pubDate>Wed, 12 May 2010 04:01:49 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Adobe Air]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/2010/05/adobe-air-2-rc-released/</guid>
		<description><![CDATA[http://labs.adobe.com/technologies/air2/ Related posts: AS spell checking engine Squiggly Adobe Air 2.0 新特性 Adobe Air on Android
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2009/09/as-spell-checking-engine-squiggly/' rel='bookmark' title='AS spell checking engine Squiggly'>AS spell checking engine Squiggly</a></li>
<li><a href='http://blog.richmediaplus.com/2009/10/new-features-in-adobe-air-2-0/' rel='bookmark' title='Adobe Air 2.0 新特性'>Adobe Air 2.0 新特性</a></li>
<li><a href='http://blog.richmediaplus.com/2010/02/adobe-air-on-android/' rel='bookmark' title='Adobe Air on Android'>Adobe Air on Android</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://labs.adobe.com/technologies/air2/">http://labs.adobe.com/technologies/air2/</a></p>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2009/09/as-spell-checking-engine-squiggly/' rel='bookmark' title='AS spell checking engine Squiggly'>AS spell checking engine Squiggly</a></li>
<li><a href='http://blog.richmediaplus.com/2009/10/new-features-in-adobe-air-2-0/' rel='bookmark' title='Adobe Air 2.0 新特性'>Adobe Air 2.0 新特性</a></li>
<li><a href='http://blog.richmediaplus.com/2010/02/adobe-air-on-android/' rel='bookmark' title='Adobe Air on Android'>Adobe Air on Android</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2010/05/adobe-air-2-rc-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe Air on Android</title>
		<link>http://blog.richmediaplus.com/2010/02/adobe-air-on-android/</link>
		<comments>http://blog.richmediaplus.com/2010/02/adobe-air-on-android/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 03:27:05 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Adobe Air]]></category>
		<category><![CDATA[Google Android]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=497</guid>
		<description><![CDATA[在 Barcelona 的 Mobile World Congress 上，Adobe 聲明了 Adobe Air 將會支持 Android 的動作，對我來說并不是新聞，我在Mobile Application的未來中就已經提到了幾點，其實當時就已經收到了風聲。 不過 Adobe Air 還有很多事情需要去做，畢竟Mobile的性能和PC的性能是無法比的，在 Developer 做好優化的同時，Adobe 自己還有一大部分工作要做。 AIR on Android 的視頻例子：http://www.adobe.com/go/airmobile Related posts: Flashplayer 10 率先登陸 Android! Mobile Application的未來 Android killProcess
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2009/06/flashplayer-10-android/' rel='bookmark' title='Flashplayer 10 率先登陸 Android!'>Flashplayer 10 率先登陸 Android!</a></li>
<li><a href='http://blog.richmediaplus.com/2009/05/mobile-application-future/' rel='bookmark' title='Mobile Application的未來'>Mobile Application的未來</a></li>
<li><a href='http://blog.richmediaplus.com/2011/11/android-killprocess/' rel='bookmark' title='Android killProcess'>Android killProcess</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>在 Barcelona 的 Mobile World Congress 上，Adobe 聲明了 Adobe Air 將會支持 Android 的動作，對我來說并不是新聞，我在<a href="http://blog.richmediaplus.com/2009/05/mobile-application-future/">Mobile Application的未來</a>中就已經提到了幾點，其實當時就已經收到了風聲。</p>
<p>不過 Adobe Air 還有很多事情需要去做，畢竟Mobile的性能和PC的性能是無法比的，在 Developer 做好優化的同時，Adobe 自己還有一大部分工作要做。</p>
<p>AIR on Android 的視頻例子：<a href="http://www.adobe.com/go/airmobile">http://www.adobe.com/go/airmobile</a></p>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2009/06/flashplayer-10-android/' rel='bookmark' title='Flashplayer 10 率先登陸 Android!'>Flashplayer 10 率先登陸 Android!</a></li>
<li><a href='http://blog.richmediaplus.com/2009/05/mobile-application-future/' rel='bookmark' title='Mobile Application的未來'>Mobile Application的未來</a></li>
<li><a href='http://blog.richmediaplus.com/2011/11/android-killprocess/' rel='bookmark' title='Android killProcess'>Android killProcess</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2010/02/adobe-air-on-android/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AIR 2.0 Sample Applications</title>
		<link>http://blog.richmediaplus.com/2009/11/air-2-0-sample-applications/</link>
		<comments>http://blog.richmediaplus.com/2009/11/air-2-0-sample-applications/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 02:00:16 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Adobe Air]]></category>
		<category><![CDATA[Air 2.0]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=397</guid>
		<description><![CDATA[AIR 2.0的示例應用 by Everything Flex 更多功能期待最終版本 No related posts.
No related posts.]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.everythingflex.com/2009/11/17/air-2-0-sample-applications/">AIR  2.0的示例應用</a> by Everything Flex<br />
更多功能期待最終版本</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2009/11/air-2-0-sample-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adobe Air 2.0 新特性</title>
		<link>http://blog.richmediaplus.com/2009/10/new-features-in-adobe-air-2-0/</link>
		<comments>http://blog.richmediaplus.com/2009/10/new-features-in-adobe-air-2-0/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 02:41:32 +0000</pubDate>
		<dc:creator>Alvin / Aedis.Ju</dc:creator>
				<category><![CDATA[Air]]></category>
		<category><![CDATA[Adobe Air]]></category>

		<guid isPermaLink="false">http://blog.richmediaplus.com/?p=365</guid>
		<description><![CDATA[應該算是目前最詳細的版本 AIR 2 Enhancements Complete Overview 完整的 AIR 2.0 新特性中文详细介绍 Related posts: Adobe Flex Application LifeCycle
Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2010/12/adobe-flex-application-lifecycle/' rel='bookmark' title='Adobe Flex Application LifeCycle'>Adobe Flex Application LifeCycle</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>應該算是目前最詳細的版本</p>
<ul>
<li><a href="http://www.insideria.com/2009/10/air-2-enhancements-complete-ov.html" target="_blank">AIR 2 Enhancements Complete Overview</a></li>
<li><a href="http://www.riahome.cn/?p=1262" target="_blank">完整的 AIR 2.0 新特性中文详细介绍</a></li>
</ul>
<p><a href="http://elromdesign.com/blog/Flex/AIR2/Main.swf"><img title="點擊體驗更多 Adobe Air 2.0 精彩" src="http://www.insideria.com/higherlevel-arct.png" alt="New features in Adobe Air 2.0" width="450" height="360" /></a></p>
<p>Related posts:<ol>
<li><a href='http://blog.richmediaplus.com/2010/12/adobe-flex-application-lifecycle/' rel='bookmark' title='Adobe Flex Application LifeCycle'>Adobe Flex Application LifeCycle</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.richmediaplus.com/2009/10/new-features-in-adobe-air-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

