unity3d 嵌入iOS的 In App Purchase 应用程序内购买
Unity做东西是快,但是有些功能是需要额外开发的,比如 IAP (In App Purchase,应用程序内购买)
还好unity提供了灵活的扩展功能,允许嵌入原生代码来做一些unity未实现的功能。
这几天折腾IAP,碰到很多问题,现在终于调通了,记下来备忘。
首先要提到两个链接:
http://troybrant.net/blog/2010/01/in-app-purchases-a-full-walkthrough/
帖子的名字a full walkthrough,翻译过来可以叫做"全攻略"或者“完全手册"
通过在google搜索关键字 in app purchase 全攻略 可以找到好心人翻译的中文版。
原作者是大好人,自己在做iap的时候,一路艰辛,搞定之后分享他的经验,提供完整好用的代码,减少后来者的痛苦。
用作者自己的话说:It took several days of blood, sweat, and tears to get it working in my own application, and hopefully this post has helped short circuit that cycle of pain and suffering for you as well.
十分感谢原作者!
可惜的是这个文章很旧了,里面有些内容已经过时,例如:
1。调试IAP必须上传App。现在已经不需要这样了,上传app之前apple已经允许你管理 InAppProduct
2。建立好Product之后需要等几个小时才能访问。这个貌似也不需要了,我弄好之后很快就能访问了。
分割线————————————————————————————————
下面开始讲代码实现和调试过程:
原作者的代码我就不贴了,只贴一段unity调用该代码的代码。
//InAppPurchase.mm
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
#import "InAppPurchaseManager.h"
extern "C" {
bool CanPurchase()
{
return ([SKPaymentQueue canMakePayments]);
}
InAppPurchaseManager *sharedMgr = nil;
void BuyPro()
{
if (sharedMgr == nil) {
sharedMgr = [[InAppPurchaseManager alloc]init];
[sharedMgr loadStore];
}
[sharedMgr purchaseProUpgrade];
}
}
代码说明:这段代码提供了两个函数
一个 CanPurchase用来判断是否可以程序内购买,如果用户通过设置关掉了程序内购买,需要提醒用户打开。
一个是购买Pro版本,即调用InAppPurchaseManager的 purchaseProUpgrade方法
原作者实现的是一个非消费型的产品,即一次付费,终身使用。如果要做消费型的产品,即每次购买都需要付费(常用的道具付费),也很简单,在iTunesConnect里面添加产品的时候选对类型就好了,代码本身都支持。
把包含上面代码的InAppPurchase.mm文件放到unity的Assets/Plugins/ios目录下,记住目录结构,不要犯错,否则xcode会链接不过,报Symbol(s) not found
另外把原作者的4个文件 也放到此目录下。4个文件分别是:
InAppPurchaseManager.h
InAppPurchaseManager.m
SKProduct+LocalizedPrice.h
SKProduct+LocalizedPrice.m
在unity脚本中使用这两个函数的代码如下:(貌似只能c#)
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class IAP: MonoBehaviour
{
[DllImport ("__Internal")]
private static extern bool CanPurchase();
[DllImport ("__Internal")]
private static extern void BuyPro();
void OnGUI()
{
if (GUI.Button(Rect(10, 10, 120, 120), "Buy"))
{
if(CanPurchase())
{
Debug.Log("can buy.");
BuyPro();
}
else
{
Debug.Log("you need open in app purchase.");
}
}
}
}
如果要反过来调用,即在原生代码中调用脚本的函数,unity提供一个方法:
UnitySendMessage("game_object", "BuyProSuccess", "Ok");
这个方法调用相当于给名为 game_object的对象调了一个SendMessage("BuyProSuccess",”Ok")
当然对象名,消息名(函数名),参数内容你可以根据自己的需要随便填,参数类型貌似只能String
可以把这行代码加到 InAppPurchaseManager.m的provideContent方法中,用来通知unity对象购买成功,作出相应的处理。
代码相关的部分就这些,其实更复杂更痛苦的更容易犯错的倒是代码之外的东西。
几个注意事项:
1。别忘了在xcode中给你的工程加上StoreKit.framework。官方指南中就一句,make sure link to StoreKit.framework,这句话折腾我半天,我还以为是链接选项呢,找半天没找到,原来是在xcode的Groups & Files窗口(左边的那个列出文件的窗口)中找Frameworks组点右键,Add -> Existing Frameworks... 在弹出对话框中找到StoreKit.framework
2。unity菜单 File-> build settings -> player settings 中 Identification一节中 Bundle Identifier必须要和你在iTunes Connect中建立应用的时候填的bundle identifier一致,一般都是com.yourcompany.appname
3。full walkthrough作者代码中的宏定义kInAppPurchaseProUpgradeProductId对应的字符串需要改成你自己在iTunesConnect中添加Product时设定的id,一般是com.yourcompany.appname.productname,不能丝毫有错,否则Invalid product id
4.在Xcode中project-》edit project settings 中build页,code signing identity->any ios的值必须是你添加app时生成的provisioning profile,即此app专用的provisioning profile,否则 invalid product id,建议删除手机中的其他无关的profile
5。如果消费型产品出现 “您已经购买产品,但尚未下载。。。”,说明事务没有正确结束,如果严格按照我的做法,应该不会出现此问题。
6。碰到各种诡异的问题,实在没辙了,可以考虑从设备中删掉你的应用,重新安装,重启设备等手段。
7。IAP不能在模拟器上运行,直接真机。当然debug或release都行。记得在你的设备上退出你的正式账号,用测试iap一定要用测试账号。测试账号建立请在member center中选择manager users。
8。将下面提供的参考链接通读3遍,有助于避免一些不必要的错误,虽然都很长,但是不要着急,慢慢看。
9。万事不决问google
参考链接:
1。原版的iap walkthrough:
http://troybrant.net/blog/2010/01/in-app-purchases-a-full-walkthrough/
中文链接http://www.cocoachina.com/bbs/read.php?tid-69165-fpage-2.html
2。apple提供的iap教程
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction/Introduction.html
3。apple提供的itunes connect开发者指南(有中文版)
https://itunesconnect.apple.com/docs/iTunesConnect_DeveloperGuide.pdf
4。unity手册中关于插件的部分
http://unity3d.com/support/documentation/Manual/Plugins.html
5。应对xcode 输出 the program being debugged is not being run错误的帖子
http://www.dragdrop.it/devcorner/2010/05/error-from-the-debugger-the-program-being-debugged-is-on-being-run/
unity3d 嵌入iOS的 In App Purchase 应用程序内购买的更多相关文章
- <转>iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!
原文地址:http://blog.csdn.net/xiaominghimi/article/details/6937097 //——2012-12-11日更新 获取"产品付费数量等于0 ...
- 【转】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程
http://blog.csdn.net/xiaominghimi/article/details/6937097 //——2012-12-11日更新 获取"产品付费数量等于0这个问题& ...
- 【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!【2012-12-11日更新获取”产品付费数量等于0的问题”】
转的别人的 看到很多童鞋问到,为什么每次都返回数量等于0?? 其实有童鞋已经找到原因了,原因是你在 ItunesConnect 里的 “Contracts, Tax, and Banking”没有完成 ...
- 详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程
Himi 原创, 欢迎转载,转载请在明显处注明! 谢谢. 原文地址:http://blog.csdn.net/xiaominghimi/article/details/6937097 //——201 ...
- [IPA]IOS In App Purchase(内购)验证
参考我之前的笔记 苹果内购笔记,在客户端向苹果购买成功之后,我们需要进行二次验证. 二次验证 IOS在沙箱环境下购买成功之后,向苹果进行二次验证,确认用户是否购买成功. 当应用向Apple服务器请求购 ...
- vue打包app嵌入h5,区分app进入和android,ios显示不同的下载链接
vue打包app嵌入h5,区分app进入和android,ios显示不同的下载链接 需求:自己app打开的登录页面不显示app下载链接.其他地方打开判断android手机的跳转到android下载页链 ...
- Unity3d调用iOS陀螺仪
How to write gyroscope controller with Unity3d http://blog.heyworks.com/how-to-write-gyroscope-contr ...
- iOS 开发 初级:应用内购买 In-App Purchase
http://blog.csdn.net/songrotek/article/details/8680415 现在有很多应用都使用了In-App Purchase,虽然对于很多用户来说,可能并不喜欢甚 ...
- IOS APP 国际化 程序内切换语言实现 不重新启动系统(支持项目中stroyboard 、xib 混用。完美解决方案)
上篇 IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源 介绍了纯代码刷新 实现程序内切换语言. 但效率底下,也存在一些问题.暂放弃. ...
随机推荐
- python_网络编程socketserver模块实现多用户通信
服务端: import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): #在这个函数里面 ...
- Oracle-锁的查询和处理
1.查出锁定object的session的信息以及被锁定的object名 SELECT L.SESSION_ID SID, S.SERIAL#, L.LOCKED_MODE, L.ORACLE_USE ...
- JAVA实现WEBSERVICE 上传下载
因公司新项目决定使用webservice与其它项目做交互,于是开始了webservice之旅. 初入webservice的时候第一个接触的工具叫axis2,网上有着大量的简单案例.功能很强大,代 ...
- selenium怎样避免被服务器检测
selenium是用来完成浏览器自动化相关的操作.可以通过代码的形式制定一些基于浏览器自动化的相关操作(行为动作),当代码执行后,浏览器就会自动触发相关的事件.但这并不能避免服务器的检测.当在浏览器中 ...
- python原生操作mysql
import pymysql HOST = '127.0.0.1' PORT = 3306 USER = 'root' PASSWD = ' DB = 'test' CHARSET = 'utf8' ...
- Vue项目开发最新、最全代码规范文档
Vue项目开发最新.最全代码规范文档 2019年02月21日 10:43:49 yw00yw 阅读数 337 一. 目录结构 |— build 构建脚本目录 |— build.js 生产环境构建( ...
- web文件夹上传
需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500M内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以501M来进行限制. 第一步: 前端修改 由于项目使用的是 ...
- 【luoguP1840】 Color the Axis_NOI导刊2011提高(05)
题目描述 在一条数轴上有N个点,分别是1—N.一开始所有的点都被染成黑色.接着我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色.请输出每个操作执行后剩余黑色点的个数. 输入格式 输入一行为N ...
- busTrace VS HW protocol analyzer - 好东西推荐
最近在找PCIe/NVMe协议分析仪,发现一款软件分析仪:busTRACE,非常不错的工具,对于从事协议开发的同胞们,是个福利,下面把硬件和软件两种分析仪的各自的优势比较了一下(来自busTrace文 ...
- java试题复盘——9月8日
上: 1.可将语句块或方法设为同步使用的语句是(A) A synchronized 用于方法或者代码块前,使此方法或者代码变成同步的 B static ...