将打印重定向到文件,如将NSLog重定向到文件

时间:2016-02-22 14:08:39

标签: ios swift nslog

我已使用宏将 NSLog 重定向到文件

但我无法迅速找到一种稳定的方法来做到这一点。

截至目前,我正在做一个解决方法

我定义了以下方法,因此每当我在文件中调用print时,它就会出现在文件中。

func print(log:String!) {
        if let logg = log {
            DeveloperConsoleManager.sharedInstance.writeOnConsoleLog(logg)
        }
    }

但这种方法的问题是

1.我将在电话中额外参数 如果我喜欢下面

print("some comments",Obj1,Obj2)

所以我必须像这样使用

print("some comments \(Obj1) \(Obj2)")

2.我会收到错误,如无法转换类型' [AnyObject]'预期参数类型'字符串!' 如果我尝试直接打印对象

print(obj)

所以我必须调用对象的描述方法

print(obj.description)

3. 我必须在上面引用的功能定义中包含我想要此功能的地方但是在NSLog的情况下,它在一个地方全局定义

所以现在我正在寻找一个稳定的解决方案将swift中打印的内容重定向到文件

所以我可以像在swift中一样使用 print

更新

我试过覆盖打印但我得到方法不会覆盖其超类中的任何方法

2 个答案:

答案 0 :(得分:5)

首先,使用宏覆盖NSLog非常糟糕。只需使用不同的函数名称并使用它。覆盖print更加脆弱。只需将其他名称命名即可。当有人在代码中看到NSLogprint时,这不应该是一招。

那就是说,只要你给它正确的签名,它通常会在一个给定的模块中工作:

public func print(items: Any..., separator: String = "", terminator: String = "\n")

(编辑:修正了签名,确切地说明了print的确切方式,而不仅仅是显示文档。)

您在函数中没有使用varargs语法(...),这就是它不接受多个参数的原因。如果您希望它接受非字符串(例如obj),那么您必须接受Any,而不仅仅是String

如果您只是制作自己的printlog函数(或任何您想要的函数),那么当然您可以使用任何方便的签名,但如果您要重载print,你需要匹配它的签名和功能。

这是完整的实施。这是一种可怕的方式。您不应该覆盖print。但这就是Swift允许它完成的方式(分散在三个文件中只是为了证明它正在工作):

main.swift:

func print(items: Any..., separator: String = "", terminator: String = "\n") {
    Swift.print("My print is printing \(items)", separator: separator, terminator: terminator)
}

print("In main!")
file1print()
file2print()

file1.swift:

func file1print() {
    print("file1!") // Calls our print
}

file2.swift:

func file2print() {
    print("file2!") // Calls our print
}

同样,这是一个可怕的想法。只需创建一个新功能,它就会更好,更灵活,更清晰。但斯威夫特绝对可以做到。

作为一个注释,如果您的真正目标只是将stdout或stderr写入文件,则无需以这种方式覆盖print或NSLog。只需重新打开你的stdout和/或stderr。例如:

let path: NSString = ...;
freopen(path.UTF8String, "a+", stderr)

那将重定向stderr。使用stdout获取stdout。这适用于打印到stdout / err的任何内容,无论它是什么模块。

答案 1 :(得分:2)

如果我敢在切线下去......

重定向NSLog的最安全方法是重定向其输出,而不是试图捕获为其提供输入的人。

How to redirect STDOUT to a NSTextView?的答案是一个合适的起点 - NSPipeNSFileHandledup2也可在iOS上使用。