LoginSignup
161
162

More than 5 years have passed since last update.

AppDelegateに良く組み込む処理

Last updated at Posted at 2014-08-02

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

161
162
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
161
162