UIApplicationDelegateプロトコルの実装から良く呼び出す処理のメモです。
アプリ起動時
– application:didFinishLaunchingWithOptions:
から呼び出す各種初期化、設定処理。
Exceptionをコンソールに出力するよう設定
例外発生時、開発中はトレースをコンソールに書き出し。これはmain.mでやっても良さそうです。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
OFF | OFF | ON |
void exceptionHandler(NSException *exception) {
NSLog(@"stackSymbols:%@", [exception callStackSymbols]);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#if DEBUG
NSSetUncaughtExceptionHandler(&exceptionHandler);
#endif
}
参考:How do you print out a stack trace to the console/log in Cocoa?
通信ログ
AFNetworkingでの通信をコンソールに出力するため、AFNetworkActivityLoggerをON/OFF。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
OFF | OFF | ON |
#if DEBUG
[[AFNetworkActivityLogger sharedLogger] startLogging];
[[AFNetworkActivityLogger sharedLogger] setLevel:AFLoggerLevelDebug];
#endif
TestFlight初期化
テスト配信にTestFlightを使っているのでその初期化です。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
ON | OFF | OFF |
[TestFlight takeOff:<TEST_FLIGHT_ID>];
NewRelic初期化
NewRelicで各種測定をする時はその初期化。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
ON | ON | ON |
[NewRelicAgent startWithApplicationToken:<NEWRELIC_ID>];
クラッシュレポート系SDK初期化
CrittercismやCrashlyticsの初期化をしています。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
ON | ON | OFF |
[Crittercism enableWithAppID:<CRITTERCISM_ID>];
リモートエラーログ
例外は発生していないが、エラーである状態をNSAssertが検知した時、配信版アプリでは(送信して良い時は)端末からログを送信、開発中はログを送信せずにその箇所でブレークする。
// デバッグ時はここでブレーク
// 配信版はTTSAssertHandlerのメソッドが呼び出される。(TTSAssertHandlerは後述)
NSAssert(object, @"objectがありません");
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
ログ送信 | ログ送信 | NSAssertの箇所でブレーク |
リモートログ送信先
- Crashlytics(CLS_LOG)
- Crittercism(logHandledException)
- TestFlightリモートログ(TFLog)
- Google AnalyticsにExceptionとして書き込む(100文字以内) (GAIDictionaryBuilderクラスのcreateExceptionWithDescription:withFatal:)
- NSLoggerで特定のMacに書き込む。
- AirBrake SDKでExceptionとしてAirbrakeに投げる
NSAssertHandlerの子クラス
#import <Foundation/Foundation.h>
@interface TTSAssertionHandler : NSAssertionHandler
@end
#import "TTSAssertionHandler.h"
@implementation TTSAssertionHandler
- (void)handleFailureInMethod:(SEL)selector
object:(id)object
file:(NSString *)fileName
lineNumber:(NSInteger)line
description:(NSString *)format, ...
{
va_list args;
va_start(args, format);
NSString *header = [NSString stringWithFormat:@"[%@ %@ %i]", NSStringFromClass([object class]), NSStringFromSelector(selector), line];
NSString *reason = (format) ? [[NSString alloc] initWithFormat:format arguments:args] : nil;
NSString *log = [NSString stringWithFormat:@"%@ %@ %@", header, reason, object]];
va_end(args);
// ここでどこかにlog送信
}
- (void)handleFailureInFunction:(NSString *)functionName
file:(NSString *)fileName
lineNumber:(NSInteger)line
description:(NSString *)format, ...
{
va_list args;
va_start(args, format);
NSString *header = [NSString stringWithFormat:@"[%@:%i]", functionName, line];
NSString *reason = (format) ? [[NSString alloc] initWithFormat:format arguments:args] : nil;
NSString *log = [NSString stringWithFormat:@"%@ %@", header, reason]];
va_end(args);
// ここでどこかにlog送信
}
@end
参考:NSAssertionHandler and NSAssert
スタブ
APIとの通信が発生するアプリでOHHTTPStubsを使ってモックデータを返す必要がある場合のみ、設定しています。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
OFF | OFF | 必要時のみON |
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
// requestがスタブを有効にしたいURLの時にYESを返す
return YES;
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) {
NSString *fileName = @"<ファイル名>";
NSString *fixture = OHPathForFileInBundle(fileName, nil);
return [OHHTTPStubsResponse responseWithFileAtPath:fixture
statusCode:200
headers:@{<ヘッダー>}];
}];
アクセス解析用SDK
Google Analytics SDK等、アクセス解析用のSDKを初期化。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
ON(開発用) | ON(本番用) | ON(開発用) |
[GAI sharedInstance].trackUncaughtExceptions = NO;
[GAI sharedInstance].dispatchInterval = 10;
[[[GAI sharedInstance] logger] setLogLevel:kGAILogLevelNone];
[[GAI sharedInstance] trackerWithTrackingId:<GA_TRACKING_ID>];
Lumberjack
ロギングにLumberjackを使っている時のみ初期化。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
OFF | OFF | ON |
//https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
[DDLog addLogger:[DDASLLogger sharedInstance]];
[DDLog addLogger:[DDTTYLogger sharedInstance]];
[[DDTTYLogger sharedInstance] setColorsEnabled:YES];
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor orangeColor] backgroundColor:nil forFlag:LOG_FLAG_INFO];
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor redColor] backgroundColor:nil forFlag:LOG_FLAG_ERROR];
キーチェーンからデータ復元
暗号化しておきたい情報はキーチェーンに保存しているので、そのデータを復元。SSKeychainを使用。
キーチェーンのクリア
開発中に初期状態のキーチェーンを使いたいケースが多々あるので、クリアする機能を持たせています。これもSSKeychain。
DB作成もしくはマイグレーション
DBを使うときはDB作成、バージョンアップ時はそのマイグレーション。
DBのクリア
デバッグ中に初期状態のDBを使いたいケースが多々あるので、デバッグ中のみDBクリアする機能を持たせています。
通知
通知を使用する場合のみ。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
ON | ON | ON |
- DeviceToken取得
static inline BOOL IsEmpty(id thing) {
return thing == nil
|| thing == [NSNull null]
|| ([thing respondsToSelector:@selector(length)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:@selector(count)]
&& [(NSArray *)thing count] == 0);
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *deviceTokenString = [[[deviceToken description]
stringByReplacingOccurrencesOfString:@"<"withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""];
if (!IsEmpty(deviceTokenString)) {
// DeviceToken保存
}
}
-
[UIApplication sharedApplication].applicationIconBadgeNumber
を0に戻す。
Facebookログイン
Facebookログインを組み込む場合のみ。
AdHoc配信版アプリ | AppStore配信版アプリ | 開発版アプリ |
---|---|---|
ON | ON | ON |
Facebookログイン後のコールバック対応
参考:[Handling the Response from the Facebook app]
(https://developers.facebook.com/docs/facebook-login/ios/v2.0#button-response "Handling the Response from the Facebook app")
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
return wasHandled;
}
セッションクローズ
- (void)applicationWillTerminate:(UIApplication *)application
{
[FBSession.activeSession close];
}
セッション更新
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// セッション更新
[FBAppCall handleDidBecomeActive];
// Facebookログインせずにホームボタンでアプリに戻った時はログインキャンセル
if (FBSession.activeSession.state == FBSessionStateClosedLoginFailed && <ログイン画面か判定>) {
// ログインキャンセル処理
}
}
参考:Facebookログイン
参考:FBAppCall仕様