CocoaLumberjackは、ログ出力を簡単に利用できるようにしたライブラリです。下記のログを出力できます。これは1つだけ行うようにすることも、全て行うことも可能です。
ここではCocoaLumberjackでログをファイルに保存し、一定間隔でAFNetworkingを使いログを送信します。せっかくなので、AFNetwokingのサンプルコードに追記していく形で紹介します。
まず、CocoaLumberjackは下記URLからダウンロードします。
その中にある「Lumberjack」ディレクトリをAFNetwokingのプロジェクトに追加します。
次に、「CustomLogFileManager」(後述)を作成するので、AFNetwokingSampleの部分でメニューを出し、[New File ...]を選択します。その後、以下のように[Objective-C class]を選択して、[Next]を選択します。
次に以下のように指定して[Next]を選択し、次に出てきたダイアログでは[Create]をそのまま選択します。
ファイルを追加する作業は以上です。現段階でのプロジェクトの状態は以下の通りです。
それではコードをいじっていきましょう。まずCocoaLumberjackを全てのクラスで扱えるように、AFNetworkingSample-Prefix.pchを変更します。
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <MobileCoreServices/MobileCoreServices.h> // 追加
#import "DDLog.h"
#endif
// 追加 ビルドがデバッグの時はVERBOSEレベルのログまで
// リリースの時はERRORだけを出力する
#ifdef DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_ERROR;
#endif
次に、AppDelegateにCocoaLumberjackの中にはDDLogというクラスがあり基本的にこれを利用して、設定とログ出力を記述します、DDLogでは下記のログ出力メソッドがあります、ログレベルに応じて使い分けましょう。
#import "AppDelegate.h"
#import "AFNetworking.h"
#import "DDTTYLogger.h"
#import "CustomLogFileManager.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// DDLog初期設定
CustomLogFileManager *logFileManager = [[CustomLogFileManager alloc] init];
// ファイルにログを出力
DDFileLogger *fileLogger = [[DDFileLogger alloc] initWithLogFileManager:logFileManager];
// 1日に1回ログファイルを更新
// fileLogger.rollingFrequency = 60 * 60 * 24;
// 10秒に1回ログファイルを更新
fileLogger.rollingFrequency = 10;
// ログファイルを残す数
fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
// Xcodeのコンソールにログを出力
[DDLog addLogger:[DDTTYLogger sharedInstance]];
[DDLog addLogger:fileLogger];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
// ios標準ボタンを作成
続いて、API接続の結果をログ出力します。
[AFJSONRequestOperation JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id json) {
// 成功した場合
// UILabelに表示 AFNetworkingはjsonを使いやすい形に渡してくれる
[self.label setText:
[NSString stringWithFormat:
@"TotalResult : %@", [json valueForKeyPath:@"TotalResult"]
]
];
DDLogInfo(@"TotalResult : %@", [json valueForKeyPath:@"TotalResult"]);
} failure:^(NSURLRequest *req, NSHTTPURLResponse *res, NSError *e, id json) {
// 失敗した場合、この時点でネットワークにつながっていない、タイムアウト、urlが間違っているなどで、ここに来る
// NSLog(@"%@", e.localizedDescription);
DDLogError(@"%@", e.localizedDescription);
}];
[operation start];
この時点で実行するとXcodeにログが出力され、ログファイルは確認できませんが、保存はされていきます。
このままでは、ただログを出力しただけなので、ファイルを送信する処理を記述します。先ほど作ったCustomLogFileManagerは、ここで利用します。
CustomLogFileManagerで継承したLogFileManagerDefaultはメソッド「didRollAndArchiveLogFile」を持っていて、これを記述するとログファイルが更新されるタイミングで呼ばれるようになります、それを利用して、ログ内容を送信します。
#import "CustomLogFileManager.h"
#import "AFNetworking.h"
@implementation CustomLogFileManager
// ログファイルが更新される際に呼ばれる
-(void)didRollAndArchiveLogFile:(NSString *)logFilePath
{
// ログファイルのパスからログ内容を取得
DDLogFileInfo *info = [DDLogFileInfo logFileWithPath:logFilePath];
NSString* content = [NSString stringWithContentsOfFile:info.filePath
encoding:NSUTF8StringEncoding
error:NULL];
// ログを送信
[self postLogData:content];
}
-(void)postLogData:(NSString *) data
{
// ログデータを表示するのでここはNSLogを使用する
NSLog(@"post data : %@", data);
// ※https://sample.urlは存在しないURLですので、失敗になりますが
// このようにエラーログなどをサーバに送ることでログ収集が可能です
NSURL *url = [NSURL URLWithString:@"https://sample.url"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
data, @"log",
nil];
[httpClient postPath:@"/log/save" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
// 成功時
NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
DDLogVerbose(@"Request Successful, response '%@'", responseStr);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 失敗時
DDLogError(@"[HTTPClient Error]: %@", error.localizedDescription);
}];
}
@end
※ログ送信先は存在しないサンプルですので、送信時にエラーになります。
これで完成です。実際に実行し、「Get json」ボタンを押下して少し待つと下記のようなログが出力されます。
以上がAFNetworkingとCocoaLumberjackの簡単な使い方でした。今回作ったサンプルもGitHubで公開しています、ぜひダウンロードしてみてください。
冒頭で説明した通り、ネットワーク接続もログ収集もアプリ開発において欠かせない要素になっていますが、実装を行う際には、ネットワーク接続もログ収集も複雑な処理を丁寧に書かなければならないため、その部分をライブラリに置き換えることができるのは品質、可読性の向上につながります。
次回はSNS連携とBaaSの活用などを紹介します。
株式会社ソニックス Co-Founder&Architect
「TNV(作らずに、ニーズを満たし、バリューを上げる)」をモットーに各種スマートデバイスアプリケーション開発におけるシステム設計や先進技術を使用した開発に従事。「たっちー」の愛称で親しまれていると誤解している、趣味はグランドハープのミニおっさん。
株式会社ソニックス スマートデバイスソリューション事業部
板前から転身したエンジニア。iOS開発歴3年。今は自社クラウドサービス「Scirocco Cloud」の開発を日々行っています。趣味は醤油工場めぐり。
Copyright © ITmedia, Inc. All Rights Reserved.