IAPExample .cs -------------------------------------------------------------------------------------------------using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; public class IAPExample : MonoBehaviour { public List<string> productInfo = new List<string>(); [DllImport("__Internal")] private static extern void TestMsg();//测试信息发送 [DllImport("__Internal")] private static extern void TestSendString(string s);//测试发送字符串 [DllImport("__Internal")] private static extern void TestGetString();//测试接收字符串 [DllImport("__Internal")] private static extern void InitIAPManager();//初始化 [DllImport("__Internal")] private static extern bool IsProductAvailable();//判断是否可以购买 [DllImport("__Internal")] private static extern void RequstProductInfo(string s);//获取商品信息 [DllImport("__Internal")] private static extern void BuyProduct(string s);//购买商品 //测试从xcode接收到的字符串 void IOSToU(string s){ Debug.Log ("[MsgFrom ios]"+s); } //获取product列表 void ShowProductList(string s){ productInfo.Add (s); } //获取商品回执 void ProvideContent(string s){ Debug.Log ("[MsgFrom ios]proivideContent : "+s); } // Use this for initialization void Start () { InitIAPManager(); } // Update is called once per frame void Update () { } void OnGUI(){ /*if(GUILayout.Button("Test 1",GUILayout.Width(200), GUILayout.Height(100))) TestMsg(); GUILayout.Space (200); if(GUILayout.Button("Test 1",GUILayout.Width(200), GUILayout.Height(100))) TestSendString("This is a msg form unity3d\tt1\tt2\tt3\tt4"); GUILayout.Space (200); if(GUILayout.Button("Test 1",GUILayout.Width(200), GUILayout.Height(100))) TestGetString(); /********通信测试***********/ if(Btn ("GetProducts")){ if(!IsProductAvailable()) throw new System.Exception("IAP not enabled"); productInfo = new List<string>(); RequstProductInfo("com.dollar.one\tcom.dollar.two"); } GUILayout.Space(40); for(int i=0; i<productInfo.Count; i++){ if(GUILayout.Button (productInfo[i],GUILayout.Height (100), GUILayout.MinWidth (200))){ string[] cell = productInfo[i].Split('\t'); Debug.Log ("[Buy]"+cell[cell.Length-1]); BuyProduct(cell[cell.Length-1]); } } } bool Btn(string msg){ GUILayout.Space (100); return GUILayout.Button (msg,GUILayout.Width (200),GUILayout.Height(100)); } } --------------------------------------------------------------------- ---------------------------------------------------------------------// // UJSInterface.h // Unity-iPhone // // Created by MacMini on 14-5-15. // // #import <Foundation/Foundation.h> @interface IAPInterface : NSObject @end // // UJSInterface.m // Unity-iPhone // // Created by MacMini on 14-5-15. // // #import "IAPInterface.h" #import "IAPManager.h" @implementation IAPInterface void TestMsg(){ NSLog(@"Msg received"); } void TestSendString(void *p){ NSString *list = [NSString stringWithUTF8String:p]; NSArray *listItems = [list componentsSeparatedByString:@"\t"]; for (int i =0; i<listItems.count; i++) { NSLog(@"msg %d : %@",i,listItems[i]); } } void TestGetString(){ NSArray *test = [NSArray arrayWithObjects:@"t1",@"t2",@"t3", nil]; NSString *join = [test componentsJoinedByString:@"\n"]; UnitySendMessage("Main", "IOSToU", [join UTF8String]); } IAPManager *iapManager = nil; void InitIAPManager(){ iapManager = [[IAPManager alloc] init]; [iapManager attachObserver]; } bool IsProductAvailable(){ return [iapManager CanMakePayment]; } void RequstProductInfo(void *p){ NSString *list = [NSString stringWithUTF8String:p]; NSLog(@"productKey:%@",list); [iapManager requestProductData:list]; } void BuyProduct(void *p){ [iapManager buyRequest:[NSString stringWithUTF8String:p]]; } @end --------------------------------------------------------------------- ---------------------------------------------------------------------// // IAPManager.h // Unity-iPhone // // Created by MacMini on 14-5-16. // // #import <Foundation/Foundation.h> #import <StoreKit/StoreKit.h> @interface IAPManager : NSObject<SKProductsRequestDelegate, SKPaymentTransactionObserver>{ SKProduct *proUpgradeProduct; SKProductsRequest *productsRequest; } -(void)attachObserver; -(BOOL)CanMakePayment; -(void)requestProductData:(NSString *)productIdentifiers; -(void)buyRequest:(NSString *)productIdentifier; @end ---------------------------------------------------------------- // // IAPManager.m // Unity-iPhone // // Created by MacMini on 14-5-16. // // #import "IAPManager.h" @implementation IAPManager -(void) attachObserver{ NSLog(@"AttachObserver"); [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; } -(BOOL) CanMakePayment{ return [SKPaymentQueue canMakePayments]; } -(void) requestProductData:(NSString *)productIdentifiers{ NSArray *idArray = [productIdentifiers componentsSeparatedByString:@"\t"]; NSSet *idSet = [NSSet setWithArray:idArray]; [self sendRequest:idSet]; } -(void)sendRequest:(NSSet *)idSet{ SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:idSet]; request.delegate = self; [request start]; } -(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ NSArray *products = response.products; for (SKProduct *p in products) { UnitySendMessage("Main", "ShowProductList", [[self productInfo:p] UTF8String]); } for(NSString *invalidProductId in response.invalidProductIdentifiers){ NSLog(@"Invalid product id:%@",invalidProductId); } [request autorelease]; } -(void)buyRequest:(NSString *)productIdentifier{ SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } -(NSString *)productInfo:(SKProduct *)product{ NSArray *info = [NSArray arrayWithObjects:product.localizedTitle,product.localizedDescription,product.price,product.productIdentifier, nil]; return [info componentsJoinedByString:@"\t"]; } -(NSString *)transactionInfo:(SKPaymentTransaction *)transaction{ return [self encode:(uint8_t *)transaction.transactionReceipt.bytes length:transaction.transactionReceipt.length]; //return [[NSString alloc] initWithData:transaction.transactionReceipt encoding:NSASCIIStringEncoding]; } -(NSString *)encode:(const uint8_t *)input length:(NSInteger) length{ static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; NSMutableData *data = [NSMutableData dataWithLength:((length+2)/3)*4]; uint8_t *output = (uint8_t *)data.mutableBytes; for(NSInteger i=0; i<length; i+=3){ NSInteger value = 0; for (NSInteger j= i; j<(i+3); j++) { value<<=8; if(j<length){ value |=(0xff & input[j]); } } NSInteger index = (i/3)*4; output[index + 0] = table[(value>>18) & 0x3f]; output[index + 1] = table[(value>>12) & 0x3f]; output[index + 2] = (i+1)<length ? table[(value>>6) & 0x3f] : '='; output[index + 3] = (i+2)<length ? table[(value>>0) & 0x3f] : '='; } return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; } -(void) provideContent:(SKPaymentTransaction *)transaction{ UnitySendMessage("Main", "ProvideContent", [[self transactionInfo:transaction] UTF8String]); } -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{ for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: [self completeTransaction:transaction]; break; case SKPaymentTransactionStateFailed: [self failedTransaction:transaction]; break; case SKPaymentTransactionStateRestored: [self restoreTransaction:transaction]; break; default: break; } } } -(void) completeTransaction:(SKPaymentTransaction *)transaction{ NSLog(@"Comblete transaction : %@",transaction.transactionIdentifier); [self provideContent:transaction]; [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } -(void) failedTransaction:(SKPaymentTransaction *)transaction{ NSLog(@"Failed transaction : %@",transaction.transactionIdentifier); if (transaction.error.code != SKErrorPaymentCancelled) { NSLog(@"!Cancelled"); } [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } -(void) restoreTransaction:(SKPaymentTransaction *)transaction{ NSLog(@"Restore transaction : %@",transaction.transactionIdentifier); [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } @end |
|