Swift 接入微信 Mars_Xlogger 填坑指南——Jinkey 原創

本文做者 Jinkey(微信公衆號 jinkey-love,官網 https://jinkey.ai
原文連接 https://jinkey.ai/post/tech/swift-jie-ru-wei-xin-mars_xlogger-tian-keng-zhi-nan
文章容許非篡改署名轉載,刪除或修改本段版權信息轉載的,視爲侵犯知識產權,咱們保留追求您法律責任的權利,特此聲明!python

示例代碼地址:
https://github.com/Jinkeycode/XloggerSwiftDemogit

支持開源,但吐槽一句,做爲公司級開源項目,文檔有點少哦,但願微信的開發大大能儘快補上。github

Step 1 下載代碼

使用 git clone 或者直接下載 zip,解壓後進入目錄 mars-master/mars/libraries,看到有一個 build_apple.py 的文件
objective-c

Step 2 編譯Mars

在終端進入工程目錄輸入shell

python build_apple.py

而後回答一系列問題
第一個問題macos

input prefix for save directory. like trunk,br,tag:
輸入保存目錄的前綴swift

第二個問題xcode

Enter menu:緩存

  1. build mars for iphone.微信

  2. build mars for iphone with bitcode.

  3. build xlog for iphone

  4. build mars for macosx.

  5. build all.

  6. exit.

選擇 3 回車,報錯:

xcodebuild: error: Unknown build action 'Center/marsmaster/mars/libraries/../marslogiphone.xcodeproj'.

!!!!clean iphoneos10.0 failed!!!

看看控制檯打印的記錄發現路徑和我目錄的路徑不一致:

Download Center/mars-master/mars/mars-log-iphone.xcodeproj

對比以後發現一個大坑:build_apple.py 的路徑不能有空格!!!

編譯成功以後生成一個以你自定義前綴的目錄,裏面就有 framwork:

從 mars-log-iphone.xcodeproj 的 iOS deployment target 來看,最低支持 iOS 7.

Step 3 引入項目

將 mars.framework 拖入 Linked Frameworks and Libraries 而且加入其餘四個系統庫,弄好以後以下:

20170102 早上的 mars.framework 漏了一個斜槓,會致使沒法編譯,20170102 下午官方已修復,請確保你把版本更新到你看這篇文章時候的最新版本。

Step 4 引入輔助庫

將編譯獲得的 log_crypt.cc(log_crypt.cc.rewriteme 直接重命名去掉 .rewriteme)、log_crypt.h 拖入 Xcode 左側目錄結構,彈出的對話框勾選「Copy items if needed」

mars-master/samples/iOS/iOSDemo/Component 目錄下的 LogHelper.hLogHelper.mmLogUtil.hLogUtil.m 拖入 Xcode 左側目錄結構,彈出的對話框勾選 「Copy items if needed」
爲了整潔,對幾個文件進行了分組

最終的文件目錄和工程目錄以下:(忽略 Appender2SwiftBridge), 下文會說到)

Step 5 橋接 Objective-C 和 C++ 代碼

新建兩個文件(不想寫的能夠直接下載 Github 下的示例代碼拖入工程)
appender-swift-bridge.h

//  Created by Jinkey on 2017/1/2.
//  Copyright © 2017年 Jinkey. All rights reserved.
//  appender-swift-bridge.h

#include <stdio.h>
#import <Foundation/Foundation.h>
#import "LogUtil.h"

typedef NS_ENUM(NSUInteger, XloggerType) {
    
    debug,
    info,
    warning,
    error,
    
};

@interface JinkeyMarsBridge: NSObject

- (void)initXlogger: (XloggerType)debugLevel releaseLevel: (XloggerType)releaseLevel path: (NSString*)path prefix: (const char*)prefix;
- (void)deinitXlogger;

- (void)log: (XloggerType) level tag: (const char*)tag content: (NSString*)content;

@end

appender-swift-bridge.mm

//  Created by Jinkey on 2017/1/2.
//  Copyright © 2017年 Jinkey. All rights reserved.
//  appender-swift-bridge.mm

#import "appender-swift-bridge.h"
#import <mars/xlog/appender.h>
#import <mars/xlog/xlogger.h>
#import <sys/xattr.h>

@implementation JinkeyMarsBridge

// 封裝了初始化 Xlogger 方法
// initialize Xlogger
-(void)initXlogger: (XloggerType)debugLevel releaseLevel: (XloggerType)releaseLevel path: (NSString*)path prefix: (const char*)prefix{
    
    NSString* logPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingString:path];
    
    // set do not backup for logpath
    const char* attrName = "io.jinkey";
    u_int8_t attrValue = 1;
    setxattr([logPath UTF8String], attrName, &attrValue, sizeof(attrValue), 0, 0);
    
    // init xlog
    #if DEBUG
    switch (debugLevel) {
        case debug:
            xlogger_SetLevel(kLevelDebug);
        case info:
            xlogger_SetLevel(kLevelInfo);
        case warning:
            xlogger_SetLevel(kLevelWarn);
        case error:
            xlogger_SetLevel(kLevelError);
        default:
            break;
    }
    appender_set_console_log(true);
    #else
    switch (releaseLevel) {
        case debug:
            xlogger_SetLevel(kLevelDebug);
        case info:
            xlogger_SetLevel(kLevelInfo);
        case warning:
            xlogger_SetLevel(kLevelWarn);
        case error:
            xlogger_SetLevel(kLevelError);
        default:
            break;
    }
    appender_set_console_log(false);
    #endif
    appender_open(kAppednerAsync, [logPath UTF8String], prefix);
    
}

// 封裝了關閉 Xlogger 方法
// deinitialize Xlogger
-(void)deinitXlogger {
    appender_close();
}


// 利用微信提供的 LogUtil.h 封裝了打印日誌的方法
// print log using LogUtil.h provided by Wechat
-(void) log: (XloggerType) level tag: (const char*)tag content: (NSString*)content{
    
    NSString* levelDescription = @"";
    
    switch (level) {
        case debug:
            LOG_DEBUG(tag, content);
            levelDescription = @"Debug";
            break;
        case info:
            LOG_INFO(tag, content);
            levelDescription = @"Info";
            break;
        case warning:
            LOG_WARNING(tag, content);
            levelDescription = @"Warn";
            break;
        case error:
            LOG_ERROR(tag, content);
            levelDescription = @"Error";
            break;
        default:
            break;
    }
    
    #if DEBUG
    NSLog(@"[%s][%s]%@%@", levelDescription, tag, content, @">>>該行 log 因爲目前Xlogger 在控制檯輸出中文會亂碼而使用 NSlog 輸出的, 不會記錄到 Xlogger 文件中且在 Release 版本中不會輸出到控制檯");
    #endif
}

@end

Xlogger 目前在 Xcode 的控制檯輸出中文會亂碼,不清楚是 Xcode 仍是 Xlogger 的問題,待官方解決吧
補充更新,微信在20170103下午已經修復了中文亂碼的問題,因此示例代碼中我去掉了:

#if DEBUG
NSLog(@"[%s][%s]%@%@", levelDescription, tag, content, @">>>該行 log 因爲目前Xlogger 在控制檯輸出中文會亂碼而使用 NSlog 輸出的, 不會記錄到 Xlogger 文件中且在 Release 版本中不會輸出到控制檯");
#endif

Step 6 橋接 Swift 和 Objective-C

新建文件 <工程名>-Bridging-Header.h,我這裏的示例工程名爲XloggerSwiftDemo 因此新建文件XloggerSwiftDemo-Bridging-Header.h
寫入如下代碼

#import "appender-swift-bridge.h"

至此,Xlogger 的基本方法已暴露給 Swift 使用了。

Step 7 初始化和反初始化 Xlogger

打開 AppDelegate.swift
在 didFinishLaunchingWithOptions 方法中加入如下代碼初始化

var jmb = JinkeyMarsBridge()
jmb.initXlogger(.debug, releaseLevel: .info, path: "/jinkeylog", prefix: "Test")

其中 initXlogger 的第一個參數是開發環境顯示日誌的級別;第二個參數是生產環境顯示日誌的級別;第三個是儲存路徑日誌的級別,我在示例代碼中封裝了 debug,info,warning,error 四個級別;第四個參數是輸入日誌文件的前綴。

在 applicationWillTerminate 方法中加入如下代碼反初始化

JinkeyMarsBridge().deinitXlogger()

Step 8 打印日誌

在想要打印日誌的地方寫入如下代碼

var jmb = JinkeyMarsBridge()
jmb.log(.debug, tag: "JinkeyIO", content: "個人公衆號是 jinkey-love")

這裏爲了說明方便而在打印日誌的地方實例化,生產環境使用建議使用單例模式實例化JinkeyMarsBridge

Xcode8 默認會在控制檯打印一大堆日誌,爲了演示效果最佳,能夠點擊 Xcode 選擇Product->Scheme->Edit Scheme

在彈出的窗口中Environment Variables 下添加 0S_ACTIVITY_MODE disable,以下圖

Step 9 分析日誌

經過如下代碼在控制檯打印出模擬器中示例程序沙盒所在的目錄

var logPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
print(logPath)

經過 MacOS 的 Finder-前往文件夾粘貼該路徑打開

能夠看到如下目錄結構

Test.mmap2 是緩存文件,不用關心,咱們須要的是 Test_20170103.xlog 文件,咱們把這個文件使用Mars提供的 Python 腳本進行解密。腳本在mars-master/mars/log/crypt/decode_mars_log_file.py
把 decode_mars_log_file.py 和 Test_20170103.xlog 拉到桌面,從 MacOS 的終端使用 cd 命令進入桌面,再輸入命令

python decode_mars_log_file.py Test_20170103.xlog

接着會在桌面生成一個 Test_20170103.xlog.log 文件,用文本編輯工具打開便可看到打印的日誌

相關文章
相關標籤/搜索