如何在Swift中使用Crashlytics登录?

Alb*_*ori 37 logging ios crashlytics swift

文章介绍如何使用Crashlytics在Objective-C登录.但是,在完成将Crashlytics和Fabric属性引用到我的项目中的安装步骤之后,我似乎无法访问该方法.

查看Crashlytics.h文件,我可以看到它使用编译器标志定义:

#ifdef DEBUG
#define CLS_LOG(__FORMAT__, ...) CLSNSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define CLS_LOG(__FORMAT__, ...) CLSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#endif
Run Code Online (Sandbox Code Playgroud)

这个块似乎根据编译器标志包装CLSNLogCLSLog函数.

所以,我想我只是直接去源,我试图直接从swift文件中引用CLSLog.仍然没有运气:

我的桥接,Header.h:

#import <Crashlytics/Crashlytics.h>
Run Code Online (Sandbox Code Playgroud)

Log.swift:

import Foundation
import Fabric
import Crashlytics

func Log(message: String) {
    NSLog("%@", message)
    CLS_LOG("%@", message)
    CLSLog("%@", message)
}
Run Code Online (Sandbox Code Playgroud)

Log函数中的最后两行抛出错误Use of unresolved identifier.除日志记录功能外,Crashlytics崩溃报告工作正常.根据这篇文章,已经实现了对Swift的日志记录支持.

至于版本,我正在运行最新版本的Fabric/Crashlytics(12月发布,在本文发布时).

(有趣的是,我可以看到/使用CLSLogv()...)

有没有人知道合并CLS_LOG用于Swift项目的正确方法?

Mik*_*ell 37

Mike来自Crashlytics.

要在Swift中使用自定义日志记录,只需使用CLSLogv或CLSNSLogv即可.您需要创建一个数组,然后在该数组上调用getVaList函数.

这是一个片段:

CLSLogv("Log something %d %d %@", getVaList([1, 2, "three"]))
Run Code Online (Sandbox Code Playgroud)

对于CLSNSLogv:

CLSNSLogv("hello %@", getVaList(["goodbye"]))
Run Code Online (Sandbox Code Playgroud)

  • 遗憾的是,@ MikeBonnell没有与Objective-C宏相同的安全措施.例如,`CLSLogv("foo%@",getVaList([]))`编译时没有警告,但会崩溃.Crashlytics需要Swift日志记录函数,只需要一个String参数,所以我们可以在swift中进行插值. (10认同)

ian*_*ian 29

这是我的版本改编自Dima的答案.我不需要参数,因为你可以在你传递的Swift字符串中进行所有格式化.

func DebugLog(_ message: String, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
    let output: String
    if let filename = URL(fileURLWithPath: file.description).lastPathComponent.components(separatedBy: ".").first {
        output = "\(filename).\(function) line \(line) $ \(message)"
    } else {
        output = "\(file).\(function) line \(line) $ \(message)"
    }

    #if targetEnvironment(simulator)
        NSLogv("%@", getVaList([output]))
    #elseif DEBUG
        CLSNSLogv("%@", getVaList([output]))
    #else
        CLSLogv("%@", getVaList([output]))
    #endif
}
Run Code Online (Sandbox Code Playgroud)

你会像这样使用它:

DebugLog("this is a log message")
DebugLog("this is a log message \(param1) \(param2)")
Run Code Online (Sandbox Code Playgroud)

编辑:更新到Swift 3.1

  • 尼斯.这应该是接受的答案. (3认同)

Dim*_*ima 21

我需要类似于CLS_LOG()Swift的东西打印出有关呼叫位置的上下文信息.通常情况下,如果没有预处理程序指令,这是不可能的,但我发现如何在Swift中非常密切地复制这种行为:https: //developer.apple.com/swift/blog/?id = 15

我们需要的标识符(#file, #function, #line)显示有关调用者的信息,如果您将它们设置为参数列表中的默认值.

注意:如果要记录可能包含%符号的错误,例如网络查询字符串,则可能会崩溃.你需要先加入字符串(例如let string = "\(filename).\(function) line \(line) $ \(message)")

Swift 3版本(注意:这是一个全局函数,所以它应该放在任何结构或类定义之外):

/// Usage:
///
/// CLS.log("message!")
/// CLS.log("message with parameter 1: %@ and 2: %@", ["First", "Second"])
///
func CLS_LOG_SWIFT(format: String = "", _ args: [CVarArg] = [], file: String = #file, function: String = #function, line: Int = #line) 
{
    let filename = URL(string: file)?.lastPathComponent.components(separatedBy: ".").first

    #if DEBUG
        CLSNSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))
    #else
        CLSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))
    #endif
}
Run Code Online (Sandbox Code Playgroud)

Swift 2版本:

// CLS_LOG_SWIFT()
// CLS_LOG_SWIFT("message!")
// CLS_LOG_SWIFT("message with parameter 1: %@ and 2: %@", ["First", "Second"])
func CLS_LOG_SWIFT(format: String = "",
    _ args:[CVarArgType] = [],
    file: String = __FILE__,
    function: String = __FUNCTION__,
    line: Int = __LINE__)
{
    let filename = NSURL(string:file)?.lastPathComponent?.componentsSeparatedByString(".").first

    #if DEBUG
        CLSNSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))
    #else
        CLSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))
    #endif

}

// CLS_LOG() output: -[ClassName methodName:] line 10 $
// CLS_LOG_SWIFT() output: ClassName.methodName line 10 $
Run Code Online (Sandbox Code Playgroud)

这里有一些关于更多信息的要点以及我将此代码放入的实际文件:https://gist.github.com/DimaVartanian/a8aa73ba814a61f749c0

正如您所看到的,它非常接近原始宏,只是区别在于您无法查看是否正在调用类方法或实例方法,并且您需要包含数组中包含的格式参数列表.两者都是局限性我认为现在没有办法,但很小.您还需要确保在Swift编译器标志中定义了DEBUG.它不会自动从常规标志中继承.


Por*_*ins 11

你必须像这样创建一个中间桥:

CrashlyticsBridge.h:

#import <Foundation/Foundation.h>

@interface CrashlyticsBridge : NSObject

+ (void)log:(NSString *)message;

@end
Run Code Online (Sandbox Code Playgroud)

CrashlyticsBridge.m

#import "CrashlyticsBridge.h"
#import <Crashlytics/Crashlytics.h>

@implementation CrashlyticsBridge

+ (void)log:(NSString *)message {
    CLS_LOG(@"%@", message);
}

@end
Run Code Online (Sandbox Code Playgroud)

我的桥接,Header.h:

#import "CrashlyticsBridge.h"
Run Code Online (Sandbox Code Playgroud)

然后,您只需将其添加到您的Log函数:

func Log(message: String) {
    CrashlyticsBridge.log(message)
}
Run Code Online (Sandbox Code Playgroud)

这将在您调试时为您提供Crashlytics日志记录和NSLogging.