AppDelegateに良く組み込む処理

  • 169
    いいね
  • 1
    コメント
この記事は最終更新日から1年以上が経過しています。

UIApplicationDelegateプロトコルの実装から良く呼び出す処理のメモです。

アプリ起動時

– application:didFinishLaunchingWithOptions:から呼び出す各種初期化、設定処理。

Exceptionをコンソールに出力するよう設定

例外発生時、開発中はトレースをコンソールに書き出し。これはmain.mでやっても良さそうです。

AdHoc配信版アプリ AppStore配信版アプリ 開発版アプリ
OFF OFF ON
AppDelegate.h
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初期化

CrittercismCrashlyticsの初期化をしています。

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の子クラス

TTSAssertHandler.h
#import <Foundation/Foundation.h>
@interface TTSAssertionHandler : NSAssertionHandler
@end
TTSAssertHandler.m
#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

参考:NSAssertion​Handler 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

 - (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仕様