如何检测是否有任何外部库正在调用[UIDevice currentDevice] uniqueIdentifier]?

时间:2013-03-25 20:00:26

标签: ios uniqueidentifier udid uidevice

所以,since Apple is now rejecting apps that access UDID,在我们公司的当前项目中,我们需要删除所有调用此属性的API:

[[UIDevice currentDevice] uniqueIdentifier]

我们已经删除了自己代码中的所有调用,但需要确保我们使用的许多外部库都没有调用此属性。

确定某个库是否正在调用此属性的最可靠方法是什么?

提前谢谢!

3 个答案:

答案 0 :(得分:14)

除了使用otx(似乎已经变得不稳定)之外,一个选项是在该方法上设置符号断点,然后运行应用程序一段时间,看看你是否点击它。

为该方法配置符号断点如下所示:

enter image description here

如果你曾经遇到过这个断点,你可以通过打开调试器控制台并输入bt来找出谁打过它。在这种情况下,呼叫来自我的application:didFinishLaunchingWithOptions:,但无论是谁调用它都会有效:

(lldb) bt
* thread #1: tid = 0x1c03, 0x001f4690 UIKit`-[UIDevice uniqueIdentifier], stop reason = breakpoint 1.1
frame #0: 0x001f4690 UIKit`-[UIDevice uniqueIdentifier]
frame #1: 0x0000212e MyApp`-[AppDelegate application:didFinishLaunchingWithOptions:](self=0x0747fcb0, _cmd=0x005aec21, application=0x08366300, launchOptions=0x00000000) + 702 at AppDelegate.m:37
frame #2: 0x00015157 UIKit`-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 266
frame #3: 0x00015747 UIKit`-[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1248
frame #4: 0x0001694b UIKit`-[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 805
frame #5: 0x00027cb5 UIKit`-[UIApplication handleEvent:withNewEvent:] + 1022
frame #6: 0x00028beb UIKit`-[UIApplication sendEvent:] + 85
frame #7: 0x0001a698 UIKit`_UIApplicationHandleEvent + 9874
frame #8: 0x01f01df9 GraphicsServices`_PurpleEventCallback + 339
frame #9: 0x01f01ad0 GraphicsServices`PurpleEventCallback + 46
frame #10: 0x01f1bbf5 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
frame #11: 0x01f1b962 CoreFoundation`__CFRunLoopDoSource1 + 146
frame #12: 0x01f4cbb6 CoreFoundation`__CFRunLoopRun + 2118
frame #13: 0x01f4bf44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #14: 0x01f4be1b CoreFoundation`CFRunLoopRunInMode + 123
frame #15: 0x0001617a UIKit`-[UIApplication _run] + 774
frame #16: 0x00017ffc UIKit`UIApplicationMain + 1211
frame #17: 0x00001d42 MyApp`main(argc=1, argv=0xbffff3f8) + 130 at main.m:16

答案 1 :(得分:3)

扩展Quinn的答案:

  • strings按照每个类首次出现的顺序列出编译对象或库中的所有符号。如果在输出中看到uniqueIdentifier,则可能是他们正在使用该名称调用其他方法。但如果您在输出中看到currentDevice后紧跟uniqueIdentifier,那么他们几乎肯定会调用[[UIDevice currentDevice] uniqueIdentifier]。如果库在文件中先前调用currentDevice,则这两行可能不是顺序的。
  • otool -ov列出了库中的所有类,方法和导入。如果它列出uniqueIdentifier,则可能意味着库正在使用该名称定义自己的方法。在上下文中查看引用。在每个班级的底部,您会看到一个列出导入的Contents of (__DATA,__objc_classrefs) section部分。如果您在引用_OBJC_CLASS_$_UIDevice的类的导入中列出uniqueIdentifier,那么该类很有可能正在调用-[UIDevice uniqueIdentifier]
  • 为此,nm的输出类似于otool。具体来说,它不会向您显示对uniqueIdentifier的调用,但会向您显示导入UIDevice的类。

答案 2 :(得分:1)

可靠地确定闭源库是否实际调用方法可能很困难,但是有一些方法可以看出它们可能

  • 使用strings查看“uniqueIdentifier”是否出现在库中,无论其使用方式如何:

    $ strings libFoo.a | grep uniqueIdentifier

  • 使用nmotool(请参阅this answer

  • 使用otx(请参阅this answer

这些方法可以帮助打开设置断点可能会错过的潜在调用。