如何在Xamarin中使用iOS的OSLog?

4

我如何在Xamarin.iOS中使用iOS的OSLog

我已经成功地使用了以下NSLog,但我无法找到设置子系统(到包标识符)的方法,以便我可以在Console.app中过滤日志。

public class Logger
{
    #if DEBUG
    [DllImport(ObjCRuntime.Constants.FoundationLibrary)]
    private extern static void NSLog(IntPtr message);
    #endif

    public void WriteLine(string line)
    {
        #if DEBUG
        using (var nss = new NSString(line))
        {
            NSLog(nss.Handle);
        }
        #endif
    }
}
2个回答

5
在Xamarin.iOS中,有一个名为Default的静态CoreFoundation.OSLog对象可供直接使用,它将记录带有指定OSLogLevel参数(例如OSLogLevel.Debug、OSLogLevel.Error等)的消息。你可以在Xamarin.iOS代码中编写一个方法,在Debug级别上记录消息:
using CoreFoundation;
// ...

public void Write(string message)
{
    OSLog.Default.Log(OSLogLevel.Debug, message);
}

如果想要使用子系统和分类,您需要使用相应的构造函数实例化一个OSLog实例,并使用该实例记录消息。您可能希望保留对已创建实例的静态引用,并像使用OSLog.Default一样使用它。
public partial class AppDelegate : Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public static OSLog LoggerInstance;

    public override bool FinishedLaunching(UIApplication app, NSDictionary launchOptions)
    {
        LoggerInstance = new OSLog(subsystem: "subsystem", category: "category");
//...

public class SomeClass
{
    public void SomeMethod()
    {
        AppDelegate.LoggerInstance?.Log(OSLogLevel.Debug, "log message");
        // ...
    }

这将在设备日志中打印一条带有时间戳并显示指定类别的相当不错的消息。


3

OSLog 是一个 ObjC 结构体(由两个 const 字符组成),内核方法提供了 os_log_create 来分配一个。

注意:有关详细信息,请参阅 os/log.h

定义:

[DllImport("__Internal", EntryPoint = "os_log_create")]
public static extern IntPtr os_log_create(string subsystem, string category);

使用方法:

var oslog = os_log_create("some.bundle.id", "StackOverflowCategory");

FYI:您的NSLog应该包含一个作为NSString的printf格式字符串。
[DllImport (Constants.FoundationLibrary, EntryPoint = "NSLog")]
extern static void NSLog (IntPtr format, [MarshalAs (UnmanagedType.LPStr)] string s);

谢谢,但我该如何使用oslog变量来生成调试输出? - Harindaka
@Harindaka,你链接了OSLog类/对象(它是Swift框架os_log_t的包装器),所以我回答了这个问题。如果你想使用统一日志系统并将os_log_t传递给它,我建议查看os/log.h_os_log_impl是统一日志记录的基本方法(_os_log_internal已过时),你可以从C#到ObjC中转换它的参数。再次强调,你应该查看os/log.h,因为它大部分只是将os_log_type_enabled和低级别的_os_log_impl调用进行包装的宏。 - SushiHangover
抱歉,我不是太擅长Swift/Objc开发。我会看一下的。我可以从这个链接(https://forums.xamarin.com/discussion/comment/227392)看到一个方法,其签名如下:os_log_with_type(OS_LOG_DEFAULT,OS_LOG_TYPE_DEFAULT,“Hello os_log!”)。这是否与上面的oslog变量相同?如果是,我该如何导入常量OS_LOG_DEFAULT和OS_LOG_TYPE_DEFAULT或OS_LOG_TYPE_DEBUG / OS_LOG_TYPE_INFO等? - Harindaka
我实际上想要输出调试信息。 - Harindaka
@Harindaka os_log_with_type只是一个宏,用于os_log_type_enabled_os_log_impl(这在os/log.h中定义)。对于仅使用OS_LOG_TYPE_DEBUGos_log_type,您可以使用Console.Writeline。但是,如果您想控制类别、绑定子 ID 等,则 _os_log_impl是您想要的调用,因为它是 ObjC 宏和 Swift 框架正在使用的内核调用。 - SushiHangover
@SushiHangover 你是指_os_log_internal,对吗? - Sören Kuklau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接