检测是否从Xcode运行Swift应用程序

我想以编程方式确定iOS应用程序是否直接从XCode运行(无论是在模拟器还是在连接的设备上)。 我试过这里描述的-D DEBUG解决scheme,但是当我从Xcode断开连接并重新运行应用程序时,它仍然认为它处于debugging模式。 我想我正在寻找的是这个函数的Swift版本

#include <assert.h> #include <stdbool.h> #include <sys/types.h> #include <unistd.h> #include <sys/sysctl.h> static bool AmIBeingDebugged(void) // Returns true if the current process is being debugged (either // running under the debugger or has a debugger attached post facto). { int junk; int mib[4]; struct kinfo_proc info; size_t size; // Initialize the flags so that, if sysctl fails for some bizarre // reason, we get a predictable result. info.kp_proc.p_flag = 0; // Initialize mib, which tells sysctl the info we want, in this case // we're looking for information about a specific process ID. mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = getpid(); // Call sysctl. size = sizeof(info); junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); assert(junk == 0); // We're being debugged if the P_TRACED flag is set. return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); } 

你可以简单地保留C函数,并从Swift中调用它。 如何从Swift调用Objective-C代码中给出的配方也适用于纯C代码。

但是把代码翻译成Swift其实并不复杂:

 func amIBeingDebugged() -> Bool { var info = kinfo_proc() var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()] var size = strideofValue(info) let junk = sysctl(&mib, UInt32(mib.count), &info, &size, nil, 0) assert(junk == 0, "sysctl failed") return (info.kp_proc.p_flag & P_TRACED) != 0 } 

备注:

  • kinfo_proc()创build一个完全初始化的结构,所有字段设置为零,因此设置info.kp_proc.p_flag = 0是不必要的。
  • C inttypes是Int32是Swift。
  • 来自C代码的sizeof(info)必须是在Swift中的strideOfValue(info)才能包含结构填充。 使用sizeofValue(info) ,上面的代码在模拟器中对于64位设备总是返回false。 这是最难解决的部分。

Swift 3(Xcode 8)的更新:

strideofValue和相关的函数不再存在,它们被MemoryLayout所取代:

 func amIBeingDebugged() -> Bool { var info = kinfo_proc() var mib : [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()] var size = MemoryLayout<kinfo_proc>.stride let junk = sysctl(&mib, UInt32(mib.count), &info, &size, nil, 0) assert(junk == 0, "sysctl failed") return (info.kp_proc.p_flag & P_TRACED) != 0 }