谁有发布求助功能,和发布回复帮助系统源码下载功能和标记已解决问题的手机app源码??拜托!拜托!

你的位置: >
> 有米我是程序员APP源码分享大赛冠军选手专访:做开发就应该有一颗爱折腾的心
本次采访的是有米分享大赛冠军选手,APP源码论坛的用户名是有点帅,业余从事开发工作。
小编:感谢您能有时间接受我的采访,请先做一下自我介绍包括自己所从事的行业。
冬冬:我叫冬冬,29岁,毕业于宁波理工计算机技术专业,工作全靠自学。目前从事企业ERP的运维工作。一直非常热爱互联网,一次巧合接触了Android,产生了浓厚的兴趣,并利用空余时间学习。期间,在各个论坛和交流群中也结交了很多朋友,也见识了很多大牛。
小编:这次有米我是程序员APP源码分享大赛您获得了一等奖,您有什么想说的吗?
冬冬:我觉得APP源码分享这种方式很好,其实它不是一个比赛更是一个给大家交流学习的平台。让更多的人愿意分享自己的成果,互相学习共同进步。获奖其实比较侥幸,很多其他开发者分享的优质代码我个人也非常喜欢。大家多关注爱盈利的活动或许下一次的大奖就是你。
小编:好的,下面咱们谈谈你个人的开发情况,你觉得自从做开发过程中遇到的困难主要是什么?
冬冬: 项目前期的需求调研是非常至关重要的,但是领导层面的需求往往是非常宏观的,只能作为整个项目的理念。具体的业务流程和功能点则需要到每个部门的各个岗位上作调研。需求调研的越完善越细致,对中期项目的开发支持也就越大。在做需求调研中,能否将客户最实质的需求挖掘出来是一项非常困难的任务。
首先,每个用户的出发点都不一样,很多人都是基于自己的部门甚至自己的岗位去提需求,导致多个需求之间产生矛盾。这就需要我们花很大的功夫去梳理这些需求,并且去协调部门之间为利己而产生的冲突。在互不相让的情况下,还需要去合理解释和权衡最后的方案,力求能基本符合大家的需求又不损害到某一方的利益。
其次,用户配合的态度不够积极。很多人都是利用自己的空余时间去参与需求调研,这往往导致用户产生抵制心理。为了尽快的完成自己的任务,随便敷衍顾问,这将是整个项目的定时炸弹,因为一个功能点的不完善和不正确会导致整个业务流程无法顺利走通。如何观察和引导用户提出可靠的需求是顾问的必备技能。
最后,当项目上线前,一定要做好充足的培训和测试工作。基层用户是整个项目的核心,所有数据的产生都需要这些基层用户的输入,只有保证入口数据的正确性才能推动后面流程的进行。所以,培训这些基层用户是重中之重,是上线前的关键环节。
小编:你认为作为一个开发者最重要的是什么呢?
冬冬:我觉得开发者最重要的是有一颗爱折腾的心,只要有新的技术问世,就会去体验去尝试。固步自封是开发者最危险的信号,不去关注领域内的最新技术最新产品,就很快会被业界所淘汰。我们不一定需要学会每一种编程语言或者开发工具,但是自学能力的锻炼必须是持之以恒的,触类旁通也是必备技能。当新项目上来后,如何快速掌握就是体验一个开发者素质高低的时候。
小编:你当时觉得获奖的几率大吗?
冬冬:当雷霆战机出现后,觉得自己基本没戏了
小编:通过您之前对有米这个广告平台的了解以及本次活动的推广平台,您怎么看待有米和爱盈利呢?
冬冬:有米作为国内广告平台的元老,有着优秀的口碑和非常多的用户。其始终坚持&服务客户,用户第一,创造价值&的经营理念让它在如今竞争激烈的环境中立于不败之地。正是不断创新不断尝试新广告模式的精神,有米没有在洗牌大势中倒下,稳定攀升的收益是吸引开发者的最大保障。本次有米推广的视频广告更是应时而生,视频广告是在移动应用的合适场景播放一段15s广告视频,用户可以重新观看视频或中途退出,这种模式可以在很多应用场景中适用。视频的内容不是一般的贴图广告所能媲美的,这也将引领移动广告的新潮流。
本次活动依托的推广媒体是爱盈利,它是移动互联网最具影响力的盈利指导媒体,定位于服务移动互联网创业者和移动盈利的指导。它发布过很多广告平台的评测,这对开发者们有很大的帮助,大家通过评测文章可以对平台有个初步的认识,而不是盲目的使用,具有较强的客观性和指导意义。有米广告也是其测评过的其中之一,很多朋友看到了测评文章才开始和有米结缘,这是这份缘分才有了这次的活动。其实不管媒体、广告平台还是开发者,只有相互连接成为一个良性生态圈,才能实现共盈。
小编:在您做开发的路程中,有什么经验可以分享给大家的?
冬冬:很多人学习开发都会去买一些参考书,其实没什么必要,国内的所谓开发教程书很多都是翻译了下别人的WIKI和API说明,附例代码能否运行的起来更是看运气。其实作为一名程序员一名开发,最重要的是锻炼自己搜索的能力。当配到问题和难点的时候要有自己去钻研解决的能力。很多初学者都是碰什么一点问题就到处问,最好大牛们帮他代码都写好了直接能调用最好。很多时候,别人更多的是给你思路,真正去实施必须还是自己。如果什么都想依靠别人是当不好一名好的开发的。
小编:你对你的未来事业有什么计划吗?
冬冬:首先对本职工作的业务加深学习和了解,企业ERP的每个模块的学习其实都是非常费精力的。只有完全掌握每个模块才能为今后的工作带来实质性的帮助。底子打好了,才能有实力去争取升职。在此之外,对于Android的学习开发还会继续,它不一定能为自己赚多少钱,更多的是当成兴趣,提升自己价值的过程。至于创业,目前还没有一个很明确的方向和基础,可能还需要去等待一个契机。
本次有米赞助的APP源码分享大赛圆满结束,接下来会有越来越多的活动需要大家的支持,希望大家关注有米,关注爱盈利。APP源码论坛地址:
转载请注明: &
与本文相关的文章有没有人内置购买后,恢复成功的代码inapp
purchases)已解决
我的解决方案:
免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作!
原文链接地址:/2797/introduction-to-in-app-purchases
源代码下载:http://download.csdn.net/download/x/4223213
教程截图:
& & 成为ios开发者最大的好处就是,你编写的应用程序会有很多方式可以赚钱。比如,收费版,免费挂广告版,还有就是程序内置购买。
& & 程序内置购买会让你爱不释手,主要有以下原因:
除了程序本身的下载收费以外,你还可以赚更多的钱。一些用户愿意为那些额外的功能花费大量的金钱。
你可以免费发布你的程序(这样的话,用户就可以任意下载了),如果他们喜欢这个程序的话,那么就会有人愿意购买额外功能。
在你做完一个程序的时候,你可以在以后的发布版中添加更多的功能,然后这些功能可以用内置购买,这样的话,你就不用再重新制作另一个程序了。
& & 我最近正在制作的一个程序里面,我就决定先把程序免费(其中只包含一个故事),然后把更多的故事放在in-app purchase里面。
& & 在这篇教程里面,你将会学到如何使用程序内置付费来解琐本地程序里面的内容,我将向你展示一些技巧,用来应付使用程序内置购买功能时的一些异步特性。请谨慎采纳这些建议,因为我的程序也还在开发之中,但是,随着我的知识的积累,我会逐步更新教程内容以确保不误人子弟。
& & 这篇教程的前提条件你需要熟悉基本的ios编程概念,如果你还是一个ios开发新手,可以先参考这些教程。
In App Rage
& &那么,本教程将制作一个怎样的程序呢?好吧,在揭晓答案之前,我先介绍一些背景情况。。。
& &最近,我对&rage comics这玩意儿非常着迷。如果你以前从没听说过它,让我向你们介绍一下吧。它们实际上就是一些非常有趣的漫画,里面有些人非常搞笑和搞怪的人和事。
& &因此,这篇教程,我们想要做一个非常小巧的应用,叫做“In App Rage”,在这个程序里面,用户可以使用内置购买来获得一些漫画。但是,在我们开始编码之前,我们需要先用ios Developer Center和iTunes Connect来为本程序创建一个入口点。
& & 第一步,就是为这个程序创建一个App ID。所以,首先登录&iOS Developer Center,选择“App IDs”标签而,然后点击“New App ID”,如下图所示:
& & 你可以按照下面的截图,根据提示 输入描述和bundle identifier:
& &注意,你不能直接使用上面这个bundle identifier,你需要定义你自己的独一无二的identifier,通常的做法是把你的域名反过来写就行了,然后你也可以基于其它规则来制作啦。
& & 当你完成的时候,点击Submit。好,恭喜你,你现在有一个新的App ID了!现在,你将使用这个ID在iTunes Connect里面来创建一个新的应用了。
& &首先登录&iTunes Connect,点击“Manage Your Applications”,然后选择“Add New App”,并输入依次App Name,SKU
number,同时选择你之前刚刚创建好的Bundle ID。
& & 你可能不得不在你的应用程序名字上面下点功夫,因为,app名字必须是唯一的,而且我们之前为它添加了一个入口点(entry)。
& & 接下来的两页将要求你输入你的应用程序的一些信息。现在,可以随便填一些内容,因为后面还有机会再更改。但是,每个带×号的文本框你都必须要填好(包括程序截图,甚至你现在还没有截图,,造一个吧)
& &好吧,让你们看看我对于这个过程的感觉吧,请看下图:
& & 如果你像上面一样出错了,只需要随便填写一些数据就可以了。你可以使用任何图标或者截屏,只要大小合适就行了。一旦你把所有的错误都解决完以后,你就大功告成啦,oh yeah!
管理 In App Purchases
& & 在你开始编写in app purchase代码之前,你需要为此创建一个桩应用(placeholder app),同时,你必须在iTunes Connet里面设置好。所以,现在你拥有一个桩应用了,你现在只需要点击“Manage In App Purchases”按钮就行了,如下图所示:
& & 然后,点击的“Create New”,然后按照下图所示,填写相应的信息:
& & 让我们来解释下这几个文本域的含义吧:
Name:&这个名字就是在使用in-app purchase的时候会显示在iTunes Connect里面。这个名字你可以随便取,因为在你的程序里面是看不到它滴。
ID:&在苹果的开发文档里面,这个也叫做“product identifier”,这是一个唯一的字符串,用来标识你的in-app purchase。通常的做法是,使用你的bundle id,然后在最后加一个唯一的字符串。
Type:&你可以选择non-consumable(购买一次,永久使用),comsumable(购买一次,使用一次),或者subscription(自动续款)。本教程中,我们采用non-consumables。
for Sale:&当应用程序上架的时候,程序内置购买功能购买记录清空。
Tier:&设置程序内置购买的价钱。
&&& 在你完成上面的设置以后,往下滚动鼠标,然后在Display Detail section部分添加一个English entry,如下图所示:
&&& 当你的程序的内置购买功能弄好之后,你查询App Store的时候会返回你刚刚设置的信息。
&&& 你可能会奇怪,为什么我们要设置刚刚这一步(毕竟,你还是可以直接硬编码在你的程序之中啊!)好吧,很明显Apple想知道你定的价钱嘛。同时,在App Store里面会根据你填写的这些东西来显示一些信息,比如,内置付费应用排行榜。最后,如果你这一步设置了,你之后会变得很轻松。因为,它让你不用硬编码这些信息在你的代码之中。而且可以让你动态改变是允许内置购买还是禁止内置购买。
&&& 一旦你完成之后,保存entry,然后创建更多的实体(entry),和下面的截图效果类似。不要担心描述信息,我们并不会在本教程中使用它们。
&&& 你可能会注意到,这个过程要花费您不少时间,我能够相像,当你的程序有很多内置购买功能的时候,这个创建过程会有多么的烦人!幸运的是,本教程我们体会不到,但是,如果你的教程真的遇到了这种情况,,可以留言给我抱怨一下吧!:)
Retrieving Product List(提取产品列表)
&&& 在你能让用户从你的程序里面购买任何东西之前,你必须向iTunes Connect发送一个查询请求来从服务器上提取所有可用的产品列表。
&&& 我们可以直接在view controller里面添加代码来实现之,但是那样扩展性太不好了,不利于重用。所以,我们将创建一个辅助类来管理所有与in-app purchase相关的内容,然后你就可以在你的其它程序里面重用了。
&&& 在从服务器上获得产品列表的同时,这个辅助类还会记录哪些产品被购买了,哪些还没有。它会为每一个已经购买过的产品创建一个identifier,然后把它存到NSUserDefaults里面去。
&&& 好了,让我们动手实验一下吧!打开XCode,然后选择File\New Project,再选择&iOS\Application\Navigation-based Application,点击Choose。把工程命名为InAppRage,然后点击Save。
&&& 接下来,创建一个新的类来管理内置付费代码,命名为IAPHelper。首先,点击Classes分组,选择File\New File,然后是iOS\Cocoa Touch Class\Objective-C class,确保Subclass of NSObject被选中,然后点击Next。把这个文件命名为IAPHelper.m,通过确保“Also create IAPHelper.h” 被选中,然后点击Finish。
&&& 我们首先往IAPHelper.m里面添加一个方法来从iTunes Connect里面提取产品列表,代码如下:
- (void)requestProducts {
self.request = [[[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers] autorelease];
_request.delegate =
[_request start];
&&& 这个方法假设我们已经定义了一个实例变量,叫做&_productIdentifiers ,它包含了一串产品标识符,之后用来从iTunes Connect里面查询产品滴。(比如com.raywenderlich.inapprage.drummerrage)
&&& 它然后创建了一个SKProductsRequest实例,那是苹果公司写的一个类,它里面包含从iTunes Connect里面提取信息的代码。使用此类灰常easy,你只需要给它一个delegate(它必须符合SKProductsRequestDelegate 协议),然后就可以调用start方法了。
&&& 我们设置IAPHelper类本身作为delegate,那就意味着此类会收到一个回调函数,此函数(productsRequest:didReceiveResponse)会返回产品列表。
Update:&Jerry
在论坛里面指出,SKProductsRequestDelegate 协议是从SKRequestDelegate派生而来滴,而SKRequestDelegate协议有一个方法,叫做&request:didFailWithError:。此方法会在失败的时候调用,如果你喜欢的话,你可以使用此方法来代码后面的timeout方法。感谢Jerry!
&&& 好吧,接下来让我们来实现productsRequest:didReceiveResponse 方法吧,具体如下所示:
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@&Received products results...&);
self.products = response.
self.request =
[[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:_products];
&&& 这个非常简单。它首先保存返回的产品列表(是一个SKProducts的数组),然后把request设置为nil(为了释放内存),然后发出一个通知,任何侦听这个通知的对象都会收到这个消息。
&&& 接下来添加初始化代码:
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {
if ((self = [super init])) {
// Store product identifiers
_productIdentifiers = [productIdentifiers retain];
// Check for previously purchased products
NSMutableSet * purchasedProducts = [NSMutableSet set];
for (NSString * productIdentifier in _productIdentifiers) {
BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
if (productPurchased) {
[purchasedProducts addObject:productIdentifier];
NSLog(@&Previously purchased: %@&, productIdentifier);
NSLog(@&Not purchased: %@&, productIdentifier);
self.purchasedProducts = purchasedP
&&& 这个初始化代码将检测哪些产品已经被购买,哪些还没有。通过查询NSUserDefaults可以知道,然后再建立一个适当的数据结构。
&&& 好了,现在,我们已经见过最重要的代码了。接下来,我们在头文件中添加一些声明。首先,打开&IAPHelper.h,并作如下修改:
#import &Foundation/Foundation.h&
#import &StoreKit/StoreKit.h&
#define kProductsLoadedNotification
@&ProductsLoaded&
@interface IAPHelper : NSObject &SKProductsRequestDelegate& {
NSSet * _productI
NSArray * _
NSMutableSet * _purchasedP
SKProductsRequest * _
@property (retain) NSSet *productI
@property (retain) NSArray *
@property (retain) NSMutableSet *purchasedP
@property (retain) SKProductsRequest *
- (void)requestP
- (id)initWithProductIdentifiers:(NSSet *)productI
&& 这个简单地导入StoreKit 头文件,然后定义一些实例变量、函数和通知的名字。
&&&接下来,在IAPHelper.m里面添加synthesize 代码,以后内存释放代码,如下所示:
// Under @implementation
@synthesize productIdentifiers = _productI
@synthesize products = _
@synthesize purchasedProducts = _purchasedP
@synthesize request = _
// In dealloc
- (void)dealloc
[_productIdentifiers release];
_productIdentifiers =
[_products release];
_products =
[_purchasedProducts release];
_purchasedProducts =
[_request release];
_request =
[super dealloc];
&&& 最后一步,你需要添加StoreKit框架。右键点击Frameworks文件夹,然后点Add\Existing Frameworks ,然后选择&StoreKit.framework。然后选择Build\Build 编译一下,编译完之后,你的代码应该是没有错误的。(此方法在Xcode4.0以上不适用。4.0需要点击工程文件名,然后右键target,然后在build phase里面添加框架)
Subclassing for Your App
&&& 这里将创建一个IAPHelper类,这样以后你在你的程序里面只需要继承一下它,然后指定你的产品标识符(product identifier)就可以啦。许多人给我提建议,说可以从WEB服务器上把产品标识符以及其它相关信息全部弄下来,然后,当你的应用程序需要更新的时候,你就可以动态添加新的in-app purchase了。
&&& 这个提议非常好,但是,为了保持本教程的简单性,我这里就采用了硬编码的方式。
&&& 右键选中Classes 分组,然后选择File\New File,再选择&iOS\Cocoa Touch Class\Objective-C class,确保Subclass of NSObject 被复选中,然后点击Next。把这个文件命名为InAppRageIAPHelper.M,同时确保&“Also create InAppRageIAPHelper.h” 被复选中,然后点击Finish。
&& 然后,把InAppRageIAPHelper.h 替换成下列代码:
#import &Foundation/Foundation.h&
#import &IAPHelper.h&
@interface InAppRageIAPHelper : IAPHelper {
+ (InAppRageIAPHelper *) sharedH
&&& 这里把InAppRageIAPHelper类定义为IAPHelper类的子类,然后创建了一个静态方法用来创建些帮助类的单例。
&&& 接下来,把InAppRageIAPHelper.m替换成下面的代码:
#import &InAppRageIAPHelper.h&
@implementation InAppRageIAPHelper
static InAppRageIAPHelper * _sharedH
+ (InAppRageIAPHelper *) sharedHelper {
if (_sharedHelper != nil) {
return _sharedH
_sharedHelper = [[InAppRageIAPHelper alloc] init];
return _sharedH
- (id)init {
NSSet *productIdentifiers = [NSSet setWithObjects:
@&com.raywenderlich.inapprage.drummerrage&,
@&com.raywenderlich.inapprage.itunesconnectrage&,
@&com.raywenderlich.inapprage.nightlyrage&,
@&com.raywenderlich.inapprage.studylikeaboss&,
@&com.raywenderlich.inapprage.updogsadness&,
if ((self = [super initWithProductIdentifiers:productIdentifiers])) {
&&& 第一个sharedHelper方法是为了使InAppRageIAPHelper类变成一个单例类。注意,这种实现单例的方式并不是线程安全的,但是,对于本应用来说完全足够了,因为我们只有一个主线程。
&&& 接下来,我们硬编码了一组产品标识符的字符串数组,然后调用了基类的初始化方式。注意,我们在这里的字符串名字必须保持和之前在iTunes Connect里面定义的名称要一致。
&&& 然后选择Build\Build,保证没有错误再继续哦。
添加帮助类代码
&&& 我们差不多完成了我们的帮助类了,但是,在调用这个类的时候会有两个问题,我们接下来会讨论解决办法。
&& 第一个问题就是,这段代码在没有网络连接的情况下是跑不起来滴。所以,我们在使用之前,需要检查是否有网络。
&&&第二个问题,加载产品列表可以会耗费一定的时间,所以,我们需要让用户知道我们在加载产品列表,而不是神马都不显示,那样用户会以为程序出问题了。我们只需要简单的显示一个activity indicator就可以啦。
&& 关于这两个问题,我们都可以自己动手来解决,但是,你为什么要重新发明轮子呢?(译者:工作中,遇到任何“问题”的时候,这里的“问题”,我指的是有点难度的问题,或者自己一时想不清楚的问题,不要急着动手编码,你还没想清楚呢!瞎编码什么呀!不妨google一下,你会有意想不到的收获。当然,这里我并不是鼓励大家不动脑筋,而是,有时候,我们程序员需要一种“懒”。)苹果已经为我们写好了一个检测网络是否可用的代码,叫做&Reachability
class,而&Matej
Bukovinski则为我们写了一个非常好用的指示器类&reusable
progress indicator。你完全可以重用他们,而不要去重新发明轮子。
&& 所以,尽管去下载这些源代码吧,当然,你也可以直接从本教程的源码中获得上面提到的源码。
&&&一旦你下载完了这些文件,直接把MBProgressHUD.h/m&和 Reachability.h/m拖到你的项目的Classes分组下面就可以啦。同时确保&“Copy items into destination group’s folder”被复选中,然后点击Add。
&& 最后一步----你需要添加SystemConfiguration 类库,因为Reachability这个类依赖此类库。右键点击Frameworks文件夹,然后选择Add\Existing Frameworks,然后再从列表中选择SystemConfiguration.framework就可以啦。然后,编译,确保没有错误后再继续。
&& 好了,现在我们得到所有的产品列表和价格了,现在让我们把它们整合起来。
显示产品列表
&&& 打开RootViewController.h ,然后做如下修改:
// Before @interface
#import &MBProgressHUD.h&
// Inside @interface
MBProgressHUD *_
// After @interface
@property (retain) MBProgressHUD *
&& 上面只是简单的声明一些实例变量和定义MBProgressHUD 属性。
&& 然后,打开RootViewController.m,并做如下修改:
// At top of file
#import &InAppRageIAPHelper.h&
#import &Reachability.h&
// Under @implementation
@synthesize hud = _
// Uncomment viewDidLoad and add the following
self.title = @&In App Rage&;
// Uncomment viewWillAppear and add the following
self.tableView.hidden = TRUE;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productsLoaded:) name:kProductsLoadedNotification object:nil];
Reachability *reach = [Reachability reachabilityForInternetConnection];
NetworkStatus netStatus = [reach currentReachabilityStatus];
if (netStatus == NotReachable) {
NSLog(@&No internet connection!&);
if ([InAppRageIAPHelper sharedHelper].products == nil) {
[[InAppRageIAPHelper sharedHelper] requestProducts];
self.hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
_hud.labelText = @&Loading comics...&;
[self performSelector:@selector(timeout:) withObject:nil afterDelay:30.0];
&& 这里比较重要的代码在viewWillAppear里面。它首先设置table view默认情况下隐藏(table view在产品列表加载完之后会再重新显示滴)。然后,设置了一个通告,因为此类需要知道什么时候产品列表加载完了。
&& 然后再使用Reachability 来检测网络是否可用。如果可用的话,它就调用IAPHelper的requestProducts 方法来下载之前填好的产品列表。
&& 当产品列表在加载过程中的时候,我们用MBProgressHUD 显示一个“loading”界面。同时,我们还设置一个超时检测函数,当30秒过后,如果还没有加载完产品列表的话,我们就提示用户错误。
&& 所以,接下来,让我们添加一些代码来处理通告消息,和超时处理函数。
- (void)dismissHUD:(id)arg {
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
self.hud =
- (void)productsLoaded:(NSNotification *)notification {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
self.tableView.hidden = FALSE;
[self.tableView reloadData];
- (void)timeout:(id)arg {
_hud.labelText = @&Timeout!&;
_hud.detailsLabelText = @&Please try again later.&;
_hud.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@&37x-Checkmark.jpg&]] autorelease];
_hud.mode = MBProgressHUDModeCustomV
[self performSelector:@selector(dismissHUD:) withObject:nil afterDelay:3.0];
&& 第一个函数(dismissHUD)只是一个辅助函数,用来隐藏加载面板的。
&& 第二个方法(productsLoaded)是在kProductsLoadedNotification 通告消息到达的时候被触发的。它隐藏了加载面板,同时重新加载table view里面的东西,用来显示down下来的产品列表滴。
&& 最后一个方法(timeout),更新HUD并显示一个超时的消息,然后让这个HUD过一段时间再消失。
& 最后,我们需要在&RootViewController.m里面再添加一些代码来完成table view的动作,代码如下:
// Replare return 0 in numberOfRowsInSection with the following
return [[InAppRageIAPHelper sharedHelper].products count];
// In cellForRowAtIndexPath, change cell style to &subtitle&:
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
// In cellForRowAtIndexPath, under &Configure the cell&
SKProduct *product = [[InAppRageIAPHelper sharedHelper].products objectAtIndex:indexPath.row];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:product.priceLocale];
NSString *formattedString = [numberFormatter stringFromNumber:product.price];
cell.textLabel.text = product.localizedT
cell.detailTextLabel.text = formattedS
if ([[InAppRageIAPHelper sharedHelper].purchasedProducts containsObject:product.productIdentifier]) {
cell.accessoryType = UITableViewCellAccessoryC
cell.accessoryView =
UIButton *buyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
buyButton.frame = CGRectMake(0, 0, 72, 37);
[buyButton setTitle:@&Buy& forState:UIControlStateNormal];
buyButton.tag = indexPath.
[buyButton addTarget:self action:@selector(buyButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
cell.accessoryType = UITableViewCellAccessoryN
cell.accessoryView = buyB
// In viewDidUnload
self.hud =
// In dealloc
[_hud release];
&& 在这里,table view只是简单的显示IAPHelper单例里面的产品列表---这个列表我们是通过SKProductsRequest来获取的。
&& products数组里面的对象都是SKProduct的实例。它们包含了你在iTunes Connect里面设置的信息,比如title,description,price,etc.本教程中,table view只是简单的显示价格和标题。同时,我们还添加了一个“购买”按钮,现在这个“购买”还不起作用,因为我们还没有为它编码任何代码。
&& 你现在差不多可以测试一下了,但是,还有最后一件步(而且是非常重要的一步!)。你需要设置bundle identifier。点击你的InAppRage-Info.plist并修改Bundle identifier来匹配你的ios Developer Center里面的那个,如下图所示:
&& 好了,差不多了!编译并运行你的程序(你需要编译到设备上面,模拟器上是不行的),然后你会看到一个loading indicator,之后,就会显示一系列产品列表,如下图所示:
给我钱看看
&&& 这是篇超级无敌又臭又长的教程,而且最重要的部分还是没有讲到---如何处理支付,如何赚钱,接下来,马上为您揭晓!
&&& 做支付基本的几个要领如下:
你创建一个SKPayment对象,然后指定用户想要购买的产品的标识符。然后把它加到支付队列(payment queue)里面去。
StoreKit将会提醒用户“are you sure?”, 然后要求用户输入用户名和密码,然后支付,然后就会返回给你,支付成功还是失败。你也可以处理这种情况:用户已经为此付过费了,然后可以重新再下载,同时给出一个恰当的提示就可以了。
你设计一个特殊的对象来处理支付通告回调消息。这个对象需要处理支付内容下载(在我们这个教程没必要,因为我们是硬编码的),同时解琐程序里面的相关内容(我们可以通过使用NSUserDefaults类来处理,然后把值设置到purchasedProducts 里面就行啦)
&& 不要担心---当你看到代码的时候,就会发现,其实这个过程是很easy滴。再强调一次,我们为了使IAPHelper尽可能可以重用,我们将在&IAPHelper.h里面做如下修改:
// Add two new notifications
#define kProductPurchasedNotification
@&ProductPurchased&
#define kProductPurchaseFailedNotification
@&ProductPurchaseFailed&
// Modify @interface to add the SKPaymentTransactionObserver protocol
@interface IAPHelper : NSObject &SKProductsRequestDelegate, SKPaymentTransactionObserver& {
// After @interface, add new method decl
- (void)buyProductIdentifier:(NSString *)productI
然后打开IAPHelper.m 文件并作如下修改:
- (void)recordTransaction:(SKPaymentTransaction *)transaction {
// Optional: Record the transaction on the server side...
- (void)provideContent:(NSString *)productIdentifier {
NSLog(@&Toggling flag for: %@&, productIdentifier);
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:productIdentifier];
[[NSUserDefaults standardUserDefaults] synchronize];
[_purchasedProducts addObject:productIdentifier];
[[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier];
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@&completeTransaction...&);
[self recordTransaction: transaction];
[self provideContent: transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(@&restoreTransaction...&);
[self recordTransaction: transaction];
[self provideContent: transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
if (transaction.error.code != SKErrorPaymentCancelled)
NSLog(@&Transaction error: %@&, transaction.error.localizedDescription);
[[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
for (SKPaymentTransaction *transaction in transactions)
switch (transaction.transactionState)
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
- (void)buyProductIdentifier:(NSString *)productIdentifier {
NSLog(@&Buying %@...&, productIdentifier);
SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
&& 啊!好多代码啊,但是,其实都不难,我会一个个向大家解释清楚。
&& 当table view里面的buy按照被按下去的时候,它将会调用buyProductIdentifier函数。然后会创建一个新的SKPayment 对象,并且把这个对象加载到队伍中去。我们将把此类当作delegate来接收支持事务的更新消息,所以,当支付完成 的时候或者失败的时候,paymentQueue:updatedTransactions 这个函数将会被调用。
&& 如果支付成功了(或者取消了),那么provideContent 函数都会被调用。然后,重点来了---它会在NSUserDefaults里面设置一个标记,然后把这个事务加到队列中去。剩下的代码就是用来检测用户是否获得了相应的内容了。
&& 假如支付失败了,也会相应的有一个失败的通告消息会到达的。
&& 注意,这里recordTransaction 并没有任何实现。如果你可以的话,你可以去实现此方法,然后给WEB服务器发送一个消息,让服务器来做一些记录。个人来讲,我觉得实现这个方法没什么实际的用处。
& 同时,也请注意,这种方法保存支付信息是非常容易被黑的(你需要加密保存),但是,我并不是很关心这个东东,因为,任何想要破解我的程序的人,他们肯定是不愿意付钱的,in-app对他们来说没什么意义。
& 在我们使用这些代码之前,我们还需要在App Delegate里面添加一些东西,这样的话,当产品支付事务完成的时候,IAPHelper类就会得到相应的通千。所以,打开InAppRageAppDelegate.m并作如下修改:
// At top of file
#import &InAppRageIAPHelper.h&
// In application:didFinishLaunchingWithOptions
[[SKPaymentQueue defaultQueue] addTransactionObserver:[InAppRageIAPHelper sharedHelper]];
&&& 如果没有这句代码的话,那么&paymentQueue:updatedTransactions 这个函数将不会被调用,所以,造成记得要加上去!
&& 最后一步,让我们回到table view上面来。打开RootViewController.m ,然后作如下修改:
// Add new method
- (IBAction)buyButtonTapped:(id)sender {
UIButton *buyButton = (UIButton *)
SKProduct *product = [[InAppRageIAPHelper sharedHelper].products objectAtIndex:buyButton.tag];
NSLog(@&Buying %@...&, product.productIdentifier);
[[InAppRageIAPHelper sharedHelper] buyProductIdentifier:product.productIdentifier];
self.hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
_hud.labelText = @&Buying fable...&;
[self performSelector:@selector(timeout:) withObject:nil afterDelay:60*5];
// Add inside viewWillAppear
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productPurchased:) name:kProductPurchasedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(productPurchaseFailed:) name:kProductPurchaseFailedNotification object: nil];
// Add new methods
- (void)productPurchased:(NSNotification *)notification {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
NSString *productIdentifier = (NSString *) notification.object;
NSLog(@&Purchased: %@&, productIdentifier);
[self.tableView reloadData];
- (void)productPurchaseFailed:(NSNotification *)notification {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
SKPaymentTransaction * transaction = (SKPaymentTransaction *) notification.object;
if (transaction.error.code != SKErrorPaymentCancelled) {
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@&Error!&
message:transaction.error.localizedDescription
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@&OK&, nil] autorelease];
[alert show];
&& 你就要成功啦,再坚持一小会儿!
In App Purchases, Accounts, and the Sandbox
&& 当你在XCODE里面运行你的程序的时候,你并不是在运行真正的In-App Purchase服务器---你实际上是跑在沙盒服务器上面。
&& 这意味着,你可以购买任何东西而不用担心会被扣钱。但是,你需要先创建一个测试帐号,同时确保你的设备登出了apple store,这样的话,你就可以看到这个处理过程了。
& 要创建测试帐号,你可以先登际&iTunes Connect ,然后点击“Manage Users”.点击“Test User”, 然后就可以创建一个测试帐号了。
& 然后,打开你的iphone,确保你退出当前的帐号了。你可以通过打开Settings程序,然后点击&Store&,然后点&Sign out”。(大家千万注意啊!)
& 最后,运行你的程序吧。然后点击购买,输入测试帐号信息,如果一切顺利的话,你会得到如下截屏的输出!
&& 但是,等一分钟---哪有里漫画啊!!!!你没值钱当然就没有啦。。。
&& 好吧,这篇教程已经足够长了,用户购买以后可以得到漫画的任务就交由读者来完成吧。
&&&这里有相应的漫画图片资源,你可以拿去用用。
&& 本项目完整源代码:源代码下载:http://download.csdn.net/download/x/4223213
&& 如果你想学习更多关于程序内置购买的内容,请参考苹果的文档&In-App
Purchase Programming Guide。
&& 同时,也请留意Noel Llopis 写的一些非常不错的文章。
> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!
先提供几个地址,都有详细的说明,这些都是大神们给我们的指南针,供大家参考:
http://blog.csdn.net/xiaominghimi/article/details/6937097 /bbs/read.php?tid-24738.html https ...
在做内置购买的时候,我们如果使用自己本机的AppleID就会提示购买失败.必须要使用测试的Apple ID. 如下是添加 测试的Apple ID 过程 (图1 图2 图3) 登陆账号以后,点击 Manage Users,然后 选择 Test User ,最后 Add New User,根据提示填写即可. 之后要在手机里测试,还要 把手机本身的Apple ID ...
先提供几个地址,都有详细的说明,这些都是大神们给我们的指南针,供大家参考:
http://blog.csdn.net/xiaominghimi/article/details/6937097 /bbs/read.php?tid-24738.html https ...
内置应用误删只能通过再次安装,不要某掉磁盘恢复,数据会保留,包括keychain,Email设置等.误删.Localized文件,也可以拷贝别处的该文件来恢复本地化. 实用工具可以通过在Launchpad中拖曳一项图标到另一项上面来新建.
笔者以Windows XP系统的IIS5.1为例,在“Internet信息服务”控制台窗口中,右键点击本地计算机,在弹出的菜单中选择“所有任务à备份/还原配置”选项,接着在“配置备份/还原”对话框中点击“创建备份”按钮(图1),在“配置备份”对话框中为备份起个名,如果要加密备份文件,选中“使用密码加密备份”选项,然后输入加密密码,最后点击“确定”,完成 ...
来自:/1927刚刚repo sync取了最新的android代码,四个钟头前又从cupcake分支merge了一大堆东西进master.并且看到了中文输入法相关的代码了,赶紧编译了烧到真机上试了下.变化挺大的开机屏幕都换了,没有小机器人在右侧了,ANDROID几个字上有高亮区一直滑过,一个简洁的动态效果Cupcake ...
NSMutableArray * arrayName = [NSMutableArray array];
NSMutableArray * array = [NSMutableArray array];
[array removeAllObjects];
for (int i = 0; i& 10; i++) {
最近很多讨论应用内支付(IAP)的问题,但是好像很少有人看了这个 App Store Review Guidelines
(/appstore/resources/approval/guidelines.html#purchasing-currencies)之后再来看这到底是个什么问题.
引起争议的是 ...}

我要回帖

更多关于 php 用户帮助中心源码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信