运行 iPhone 模拟器时可以将 Xcode 控制台的日志输出重定向到终端吗?

Posted

技术标签:

【中文标题】运行 iPhone 模拟器时可以将 Xcode 控制台的日志输出重定向到终端吗?【英文标题】:Can you redirect log output of Xcode console to Terminal when running iPhone Simulator? 【发布时间】:2009-12-15 20:30:06 【问题描述】:

我不喜欢在模拟器中(或在设备上)调试 iPhone 应用程序时使用 Xcode 的控制台输出窗口。我希望能够使用 Unix 工具箱并使用 grep 过滤日志输出。但要做到这一点,我需要让 Xcode 将正在运行的 iPhone 应用程序的日志输出发送到终端。

有没有办法做到这一点?

【问题讨论】:

好问题。直到此刻,这才让我感到困扰。 我找到了自己问题的答案。它在cocoadev.com/index.pl?NSLogToFile 和开头的评论中“更好的是,避免潜在溢出的 C 数组并使用 Cocoa goodness...” 感谢丹的链接。我认为这是真正的答案。 【参考方案1】:

不能说它在模拟器中是如何工作的,但是重定向标准输出并不是很困难。假设您想将其通过管道传输到您自己的视图中:

#include <unistd.h>

stderr->_write = RedirectOutputToView;
stdout->_write = RedirectOutputToView;

并使用原型:

int RedirectOutputToView(void *inFD, const char *buffer, int size);

【讨论】:

我知道如何重定向标准输出。我只需要知道如何让 iPhone 应用程序在 XCode 中以调试模式运行以输出到终端的标准输出。 谢谢,但必须有更简单的方法来做到这一点。例如,如果有一种方法(我不知道)可以直接从终端在 iPhoneSimulator 中启动 iPhone 应用程序,那么日志输出可能会出现在您启动应用程序的终端窗口中。 因此将其重定向到一个文件并在其上运行 tail -f 。如果终端有一个标准输出,你不能从它的地址空间之外写入它。 如果 XCode 将其控制台日志输出写入某处的文件中,很高兴知道这样我们就可以直接使用 tail -f 了。 啊哈,我搞定了。解决方案类似于 NSString *logPath = @"/path/to/log/file.log"; freopen([logPath fileSystemRepresentation], "a", stderr);在 main() 函数中【参考方案2】:

在 XCode 6 中,日志在此处被截取:/Users/&lt;username&gt;/Library/Logs/CoreSimulator/&lt;app guid&gt;/system.logusername 当然是你的系统用户名,app guid 是 XCode 为模拟器生成的东西。

确定 app guid 是什么的最简单方法是为模拟器构建应用并查看上次更改的目录:

~ ❯❯❯ cd ~/Library/Logs/CoreSimulator
~/L/L/CoreSimulator ❯❯❯ ls -latr
total 64
-rw-r--r--   1 x  staff    519 27 Aug 21:54 ios Simulator.log
drwxr-xr-x  13 x  staff    442 27 Aug 21:54 D283605A-0BA9-43B3-AB6B-F4858BE6E45E
drwxr-xr-x  15 x  staff    510  8 Oct 03:56 425D8E41-0842-4F2D-BC22-8C3695E350EF

显然 425D8E41-0842-4F2D-BC22-8C3695E350EF 是最后修改的目录,所以现在您可以对实时日志执行 tail -f ~/Library/Logs/CoreSimulator/425D8E41-0842-4F2D-BC22-8C3695E350EF/system.log | grep keyword 或其他任何您可能想要执行的操作。

【讨论】:

最佳答案。顺便说一句,XCode 7 也是如此【参考方案3】:

我发现 this answer 可以很好地满足我的目的,尽管它需要运行模拟器才能在终端中实时流式传输:

我删除了模拟器检查并在重定向之前添加了一个 NSLog 语句,以便 XCode 控制台吐出文件的位置:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"console.log"];
NSLog(@"redirecting STDERR: %@", logPath);
freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);

我认为最强大的解决方案是使用日志库(例如CocoaLumberjack )并使用您喜欢的任何目的地对其进行配置。

【讨论】:

【参考方案4】:

我可以在终端中获取设备输出,但无法同时在 xcode 中连接调试会话(我猜是因为终端有调试连接)。

使用 idevicedebug 从终端启动应用程序。

idevicedebug -u <device uuid> run com.myco.apps.myapp

其中 com.myco.apps.myapp 是捆绑包 ID,可以在设备窗口的“已安装应用”窗格中看到。

认为 idevicedebug 是用 ideviceinstaller 安装的,可以用 brew 完成

brew install ideviceinstaller

但我建议搜索 ideviceinstaller 和 libimobiledevice (它使用的库)只是为了确定。

这是一个小烦恼,但我发现在终端中获取程序输出的最佳方式。

【讨论】:

【参考方案5】:

为什么不使用Console.app?一种查看和 grep 日志的好方法,而不是 xCode 的调试窗口或终端。默认情况下,这是 macOS 的一部分。

如果你有 C printf 语句,那么下面的 SO 有很多有用的信息: Get printf on Console.app

【讨论】:

【参考方案6】:

在 Xcode 6 中它已经这样做了。打开与您当前使用的模拟器构建关联的 System.log 文件。对我来说,它在这里:/Users/josh.lang/Library/Logs/CoreSimulator/3BB4CBFB-5A67-4E93-91B5-78E6E3658A16/system.log

它会保留所有内容,但我注意到如果我在运行我的 sim 时打开它,它也会自行重新加载。

【讨论】:

以上是关于运行 iPhone 模拟器时可以将 Xcode 控制台的日志输出重定向到终端吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 xcode 4.6.2 中使用 iphone 模拟器 5.1

Xcode 8.2.1 中的 iPhone 模拟器运行速度有点慢 [关闭]

Xcode安全区域故障与iPhone SE和4s

如何解决UIImages无法在模拟器或iPhone的Xcode中不显示的问题

iPhone sdk 3.2.3 升级问题

Xcode:“构建并运行”而不重新启动 iPhone 模拟器