うえすと開発メモ

カテゴリ: iOS

westhillapp01://urlschemetest」のような独自のURLを使って、
Unity iOSアプリを起動する方法の実装メモです。

ブラウザや他のアプリからUnity iOSアプリを起動
custom_url_scheme_03
Android版はこちら

実装時のバージョンはUnity4.0.1、Xcode4.6.1です。

Unityから吐き出されるXcodeプロジェクトに対して手動でURLスキームを設定出来るのですが、
同じ手順をビルドの度に行うのは億劫なので、Unity上でビルドする際に自動で設定されるようにします。 

参考:Build Player Pipeline

①Unityプロジェクトビューのルート(フォルダ構成で言うとAssets直下)に
「Editor」フォルダを作成し、中に"PostprocessBuildPlayer"という拡張子無しのファイルを作成します。
このファイルにスクリプトで記述した内容はビルド後に実行されるので、
Xcodeプロジェクトのinfo.plistに追記できます。

PostprocessBuildPlayer
#!/usr/bin/env python
 
import sys, os.path
 
install_path = sys.argv[1]
target_platform = sys.argv[2]
 
if target_platform != "iPhone": sys.exit()
 
info_plist_path = os.path.join(install_path, 'Info.plist')
 
file = open(info_plist_path, 'r')
plist = file.read()
file.close()
 
elements_to_add = '''
<key>CFBundleURLTypes</key>
<array>
 <dict>
  <key>CFBundleURLSchemes</key>
  <array>
   <string>【URLスキーム名】</string>
  </array>
 </dict>
</array>
'''
 
plist = plist.replace('<key>', elements_to_add + '<key>', 1)
 
file = open(info_plist_path, 'w')
file.write(plist)
file.close()
【URLスキーム名】の部分を使用したい独自スキーム名にします。
スキーム名は、URLの":"以前の部分になります。↑の例でいうと westhillapp01


②ターミナルにて「Editor」フォルダへ移動してPostprocessBuildPlayerへ以下コマンドで実行権限を与えます。
chmod +x PostprocessBuildPlayer
独自URLスキーム経由でアプリを起動するだけなら上記設定のみで可能です。

※吐き出されるXcodeプロジェクトのinfo.plistに「URL types - URL Schemes」の項目が無い場合はPostprocessBuildPlayerの実行に失敗しています。
この場合はUnityのコンソールビューのOpenEditorLogボタンでビルド実行時のログを見ることができるので、エラー情報など参照してください。
custom_url_scheme_01
自分は、PostprocessBuildPlayerの中身をBOM付きUTFで保存していたり、
改行コードがCRLFなどになってしまっていて何度か失敗しました…

ここから先はURLスキームからの起動をフックして、処理を分けたい等の場合の手順になります。


③Unityプロジェクトを一度iOS向けにビルドして、
XcodeプロジェクトからAppController.mmをコピーして、
Unityプロジェクトビューのルート(フォルダ構成で言うとAssets直下)に「Plugins/IOS」フォルダを作成して入れます。
「Plugins/IOS」にいれたソースファイルは、ビルド時にXcodeプロジェクト内の同名ファイルと自動で置き換えられます。

AppController.mm
内に↓の handleOpenURL 関数を追記します。
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    if (!url) {  return NO; }
    
    // --- Custom URL Scheme Hook ---
    // スキーム名取得
    NSString *urlScheme = [url scheme];
    NSLog( @"url scheme used to open app: %@", urlScheme );
    // URLスキーム名でNSUserDefaultsに保存
    [[NSUserDefaults standardUserDefaults] setInteger:1 forKey:urlScheme];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    return YES;
}
ここで起動時のURLスキーム名をキーにしてNSUserDefaultsにintのフラグを保存しています。

※同時に使用しているプラグイン等で handleOpenURL 関数を使用してる場合には、
プラグイン側の同関数内に // --- Custom URL Scheme Hook --- の処理を追記すれば問題ないです。
自分の環境では、prime31SocialNetworkingPluginFacebookManager.mm
handleOpenURL を使用していたので、そちらにフック処理を追記しました。


④Unity側で、カスタムURLスキーム経由での起動か否かを
以下のようにPlayerPrefsを使用して③で保存したフラグから判別することが出来ます。
bool launchFromCustomUrlScheme = PlayerPrefs.GetInt("【URLスキーム名】", 0) == 1 ? true: false;
PlayerPrefs.DeleteKey("【URLスキーム名】");

このエントリーをはてなブックマークに追加

UnityでのiOSアプリ内課金では割とポピュラーな、prime31のiOS StoreKit In App Purchase Plugin($70)を使用した、アプリ内課金の実装メモです。

Android版はこちら

prime31
https://www.prime31.com/

テストシーンが付属してあるので、そこで使われているソースを見るのが一番わかりやすいです。
ちなみにConsumableとNon-Consumableでしか試していません。
レシートの検証とAppleのHostingContentも使用していないです。
導入時のバージョンはUnity3.5.6、プラグインのバージョンは1.3.3です。

--------------------------------------------------------
※注意:ここで紹介しているバージョンは古いので
実装の際は公式で最新のドキュメントを確認することをおすすめします。
--------------------------------------------------------

※前準備として事前に、itunes connectにてアプリと課金アイテムの登録、
 テストユーザの追加を行ない、端末のAppleIDをログアウトしておく。

以下、実装の簡単な流れ

①iOS StoreKit In App Purchase Pluginをインポートした後、
 最初のシーンにStoreKitManagerプレハブとStoreKitEventListenerプレハブを配置。
 DontDestroyOnLoadで死なないようにしておく。

②アプリ内購入を開始する前にStoreKitBinding.canMakePayments()で、
 アプリ内購入の制限がかかっていないか確認する。
 制限がかかっている場合はダイアログなどで「設定→一般→機能制限→App内での購入」
 をオンにするよう促してあげると親切かも。

StoreKitBinding.requestProductData(string[] productIdentifiers)でアイテムの情報を取得する。
 取得したいアイテムのプロダクトIDを配列で引数に入れる。
 通信は非同期で行われ、問題なければStoreKitEventListener
 productListReceived( List<StoreKitProduct> productList )が呼ばれ、
 アイテム情報が取得できる。

④購入リクエストをStoreKitBinding.purchaseProduct(string productIdentifier, int quantity)で投げる。
 1番目の引数はプロダクトIDを、2番目は個数なので通常は1でよいかと。
 これでネイティブ側のアプリ内購入ダイアログが表示される。
 (初回はログインダイアログがでるので、事前登録したテストユーザでログインする)
写真
⑤購入が正常に終わると、StoreKitEventListener
 purchaseSuccessful( StoreKitTransaction transaction )が呼ばれるので、
 ここで対応するアイテム等をゴニョゴニョする。

⑥リストアの実装はStoreKitBinding.restoreCompletedTransactions()でリクエスト。
 StoreKitEventListenerrestoreTransactionsFinished()が呼ばれた後に、
 購入済みアイテムのpurchaseSuccessful( StoreKitTransaction transaction )が順次呼ばれる。

⑦その他のStoreKitEventListener内イベント
purchaseFailed( string error )
  
 購入エラー
purchaseCancelled( string error )
  
→ 購入キャンセル
productPurchaseAwaitingConfirmationEvent( StoreKitTransaction transaction )
  
→ トランザクションの完了待ち
    ※デフォルトではプラグイン側で終了させてるっぽい
restoreTransactionsFailed( string error )
  
→ リストアエラー
paymentQueueUpdatedDownloadsEvent( List<StoreKitDownload> downloads )
  
→ ホスティングシステムのDL状況
receiptValidationSuccessful()
  
→ レシートの検証完了
receiptValidationRawResponseReceived( string response )
  
→ レシートの検証レスポンス
receiptValidationFailed( string error )
  
→ レシートの検証エラー

このエントリーをはてなブックマークに追加

このページのトップヘ