この内容はAppleに買収されiTunes Connectに統合される前のTestFlightについての情報です、testflightapp.comは2015/2/26に終了です。
TestFlightのAndroidサポートは2014/3/21までなので代替サービスを検討してください。
http://help.testflightapp.com/customer/portal/articles/1450414
自分なりの使い方の要約。
https://testflightapp.com/sdk/ios/doc/
インストール
CocoaPodsでインストールする。基本的に安定バージョンを明示的に指定。
pod 'TestFlightSDK', '2.0.2'
Take Off
こんな感じの関数を用意しておくAppStoreに提出するときは#define USE_TESTFLIGHT_SDK 0
にしてコードに含めないようにしている。
#if USE_TESTFLIGHT_SDK
#import <TestFlightSDK/TestFlight.h>
#endif
/*
My Apps Custom uncaught exception catcher, we do special stuff here, and TestFlight takes care of the rest
*/
void HandleExceptions(NSException *exception)
{
NSLog(@"This is where we save the application data during a exception");
// Save application data on crash
}
/*
My Apps Custom signal catcher, we do special stuff here, and TestFlight takes care of the rest
*/
void SignalHandler(int sig)
{
NSLog(@"This is where we save the application data during a signal");
// Save application data on crash
}
- (void)initializeTestFlightWithApplicationToken:(NSString *)token
{
// installs HandleExceptions as the Uncaught Exception Handler
NSSetUncaughtExceptionHandler(&HandleExceptions);
// create the signal action structure
struct sigaction newSignalAction;
// initialize the signal action structure
memset(&newSignalAction, 0, sizeof(newSignalAction));
// set SignalHandler as the handler in the signal action structure
newSignalAction.sa_handler = &SignalHandler;
// set SignalHandler as the handlers for SIGABRT, SIGILL and SIGBUS
sigaction(SIGABRT, &newSignalAction, NULL);
sigaction(SIGILL, &newSignalAction, NULL);
sigaction(SIGBUS, &newSignalAction, NULL);
#if USE_TESTFLIGHT_SDK
#ifndef __IPHONE_7_0
[TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]];
#endif
[TestFlight takeOff:token];
#endif
}
あとはAppDelegateのdidFinishLaunchingWithOptionsあたりで呼び出す。さっきの関数もAppDelegateに入れて良い。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self initializeTestFlightWithApplicationToken@"Your App Token"];
return YES;
}
Remote Logging
TFLogを使う。ドキュメントでは以下のようにNSLogと切り替える例がある。
#define NSLog TFLog
や
#define NSLog(__FORMAT__, ...) TFLog((@"%s [Line %d] " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
それぞれのログは非同期で記録され、セッションが終わる際にTestFlightサーバに送られる。
実際は、AppStoreに提出することも想定してTARGET_APP_STOREなどの定義で処理を切りわけるんじゃないだろうか。自分の場合はUSE_TESTFLIGHT_SDKとTARGET_APP_STOREの定義は明示的に使い分け以下の様な感じにする。
#if TARGET_APP_STORE
#define MyLog(...) ;
#else
#if USE_TESTFLIGHT_SDK
#define MyLog(__FORMAT__, ...) TFLog((@"%s [Line %d] " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define MyLog(...) NSLog(__VA_ARGS__)
#endif // USE_TESTFLIGHT_SDK
#endif // TARGET_APP_STORE
ログに関するオプション
オプション名 | 型 | デフォルト | 説明 |
---|---|---|---|
logToConsole | BOOL | YES | Apple System Logにも出力するかどうか |
logToSTDERR | BOOL | YES | STDERRにも出力するかどうか |
[TestFlight setOptions:@{@"logToConsole:}[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"logToConsole"]];
// iOS SDK 6 or later
[TestFlight setOptions:@{@"logToConsole: @NO}];
Feedback API
openFeedbackViewを実行するとModalでフィードバックを送るフォーム(TextArea、Cancel Button, Submit Button)が表示される。
[TestFlight openFeedbackView];
submitFeedbackを使えばTestFlightのフォームを使わなくても文字列だけ送信できる。
NSString *feedback = @"my feedback";
[TestFlight submitFeedback:feedback];
FeedbackはTestFlight上からビルドごとに閲覧でき、TestFlightサイトから返信もできる。(メールで通知される)
リリース時
USE_TESTFLIGHT_SDK 0にすれば実行しなくなるが、Podfileをコメントアウトしてpod updateするのは面倒なので、スタティックライブラリはPods.xcconfig
のOTHER_LDFLAGSから一時的に-lTestFlight
を取り除いてビルドしている。ただ人為ミスが起きそうなのであまり良いやり方だと思わない。