使用 SalesForce SDK 桥接 ObjC 项目导致崩溃,因为无法在 SF SDK 中找到类别
Bridging an ObjC project with the SalesForce SDK causes a crash due to inability to find a category in the SF SDK
我有一个名为 Core.proj 的 iOS 项目,其中包含 SalesForce SDK,它是用 Objective-C 编写的。该项目利用 SF SDK 并将二进制文件链接到 SF 库。它做了很多事情来帮助管理我的 SF 实现。它包含在我所有其他的 Obj-C 项目中,并且在其中工作得非常好。
这是我第一次在 Swift (2.1) 中使用这个项目。我正在使用 iOS 9 和 Xcode 7.1.1。我将 Core.xcodeproj 添加到我的 Swift 项目中。然后我创建了一个 ObjC 文件。 Xcode 然后询问我是否要创建桥接头。我愿意。我创建了一个名为 Swift-Bridging-Header.h 的桥接头。这使我能够通过桥接头访问 Core.xcodeproj 中的文件。例如,我可以从桥接头访问我自己的 Salesforce 身份验证管理器版本。
在我的应用委托中,我现在想启动 OAuth(我在这里保持最小化):
let sharedManager = MyAuthenticationManager.sharedManager()
let successBlock: OAuthFlowSuccessCallbackBlock = { sfAuthInfo in }
let failureBlock: OAuthFlowFailureCallbackBlock = { sfAuthInfo in }
sharedManager.loginWithCompletion(successBlock, failure: failureBlock)
完全披露:您在此处看到的每个块都将 SFOAuthInfo 对象作为参数。为了让 Swift 读取此块,我必须将 SFOAuthInfo.h 添加到副本文件中。
现在编译一切正常,但是当我点击登录并执行上面的代码时,出现以下错误:
2015-12-04 11:53:54.879 MyApp[19108:3494140] -[UIDevice macaddress]: unrecognized selector sent to instance 0x7fcfb4903230
2015-12-04 11:53:54.890 MyApp[19108:3494140] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIDevice macaddress]: unrecognized selector sent to instance 0x7fcfb4903230'
*** First throw call stack:
(
0 CoreFoundation 0x000000010d6adf65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010f624deb objc_exception_throw + 48
2 CoreFoundation 0x000000010d6b658d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010d603f7a ___forwarding___ + 970
4 CoreFoundation 0x000000010d603b28 _CF_forwarding_prep_0 + 120
5 MyApp 0x000000010c869317 -[SFOAuthCredentials keyMacForService:] + 84
6 MyApp 0x000000010c8696b8 -[SFOAuthCredentials updateTokenEncryption] + 210
7 MyApp 0x000000010c8673ee -[SFOAuthCredentials initWithIdentifier:clientId:encrypted:] + 211
8 MyApp 0x000000010c84102c -[SFUserAccount initWithIdentifier:] + 197
9 MyApp 0x000000010c85f32d -[SFUserAccountManager createUserAccount] + 91
10 MyApp 0x000000010c831b41 -[SFAuthenticationManager loginWithCompletion:failure:account:] + 284
11 MyApp 0x000000010c831a0b -[SFAuthenticationManager loginWithCompletion:failure:] + 53
12 MyApp 0x000000010c60440c -[MyAuthenticationManager loginWithCompletion:failure:] + 124
13 MyApp 0x000000010c5dc58f _TFC18MyApp11AppDelegate5loginfS0_FT_T_ + 911
14 MyApp 0x000000010c5dfdc4 _TFC18MyApp25LandingPageViewController17loginButtonTappedfS0_FPSs9AnyObject_T_ + 68
15 MyApp 0x000000010c5dfe16 _TToFC18MyApp25LandingPageViewController17loginButtonTappedfS0_FPSs9AnyObject_T_ + 54
16 UIKit 0x000000010e1af1fa -[UIApplication sendAction:to:from:forEvent:] + 92
17 UIKit 0x000000010e313504 -[UIControl sendAction:to:forEvent:] + 67
18 UIKit 0x000000010e3137d0 -[UIControl _sendActionsForEvents:withEvent:] + 311
19 UIKit 0x000000010e312906 -[UIControl touchesEnded:withEvent:] + 601
20 UIKit 0x000000010e219aa3 -[UIWindow _sendTouchesForEvent:] + 835
21 UIKit 0x000000010e21a691 -[UIWindow sendEvent:] + 865
22 UIKit 0x000000010e1cc752 -[UIApplication sendEvent:] + 263
23 UIKit 0x000000010e1a7fcc _UIApplicationHandleEventQueue + 6693
24 CoreFoundation 0x000000010d5da0a1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
25 CoreFoundation 0x000000010d5cffcc __CFRunLoopDoSources0 + 556
26 CoreFoundation 0x000000010d5cf483 __CFRunLoopRun + 867
27 CoreFoundation 0x000000010d5cee98 CFRunLoopRunSpecific + 488
28 GraphicsServices 0x0000000113e46ad2 GSEventRunModal + 161
29 UIKit 0x000000010e1ad676 UIApplicationMain + 171
30 MyApp 0x000000010c5ddd8d main + 109
31 libdyld.dylib 0x00000001107a592d start + 1
32 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
SF SDK 有一个名为 UIDevice+SFHardware.h 的类别。在这个类别中有一个方法叫做 'macaddress'。很明显它没有正确阅读这个类别。但为什么?正如您从堆栈跟踪中看到的那样,它正在正确读取 SF SDK 中的其他文件。
我尝试了很多方法来让它工作。例如,这个:iOS - UUID generation throwing a strange exception but with UIDevice+SFHardware.h. I tried this: https://developer.salesforce.com/forums/?id=906F00000009CBvIAM。我再次完全重建项目以检查我的工作。
我不需要将这个文件添加到我的桥中,因为这个 UIDevice+SFHardware.h 只能从 ObjC 项目中的 SF SDK 访问。
不过我一定是做错了什么。任何帮助将不胜感激。
我刚刚解决了这个问题。
在您的项目 > 构建设置 > 其他链接器标志中添加:
-ObjC
-all_load
我的 SalesforceSDK 在我的 Pod 项目中。如果您这样做,请在您的 SalesforceMobileSDK-iOS 项目中设置这些标志。如果不是,Salesforce SDK 在何处编译。
事实证明这是多种因素的结合。首先,我在 Swift 项目和 Objc 项目中都缺少 -ObjC 链接器标志。感谢 DarthVadar123451 指出这一点。但我也意识到我缺少两个库:libz.dylib 和 libxml2.dylib。添加后,一切正常。我希望能帮助 运行 遇到同样问题的任何人。
我有一个名为 Core.proj 的 iOS 项目,其中包含 SalesForce SDK,它是用 Objective-C 编写的。该项目利用 SF SDK 并将二进制文件链接到 SF 库。它做了很多事情来帮助管理我的 SF 实现。它包含在我所有其他的 Obj-C 项目中,并且在其中工作得非常好。
这是我第一次在 Swift (2.1) 中使用这个项目。我正在使用 iOS 9 和 Xcode 7.1.1。我将 Core.xcodeproj 添加到我的 Swift 项目中。然后我创建了一个 ObjC 文件。 Xcode 然后询问我是否要创建桥接头。我愿意。我创建了一个名为 Swift-Bridging-Header.h 的桥接头。这使我能够通过桥接头访问 Core.xcodeproj 中的文件。例如,我可以从桥接头访问我自己的 Salesforce 身份验证管理器版本。
在我的应用委托中,我现在想启动 OAuth(我在这里保持最小化):
let sharedManager = MyAuthenticationManager.sharedManager()
let successBlock: OAuthFlowSuccessCallbackBlock = { sfAuthInfo in }
let failureBlock: OAuthFlowFailureCallbackBlock = { sfAuthInfo in }
sharedManager.loginWithCompletion(successBlock, failure: failureBlock)
完全披露:您在此处看到的每个块都将 SFOAuthInfo 对象作为参数。为了让 Swift 读取此块,我必须将 SFOAuthInfo.h 添加到副本文件中。
现在编译一切正常,但是当我点击登录并执行上面的代码时,出现以下错误:
2015-12-04 11:53:54.879 MyApp[19108:3494140] -[UIDevice macaddress]: unrecognized selector sent to instance 0x7fcfb4903230
2015-12-04 11:53:54.890 MyApp[19108:3494140] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIDevice macaddress]: unrecognized selector sent to instance 0x7fcfb4903230'
*** First throw call stack:
(
0 CoreFoundation 0x000000010d6adf65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010f624deb objc_exception_throw + 48
2 CoreFoundation 0x000000010d6b658d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010d603f7a ___forwarding___ + 970
4 CoreFoundation 0x000000010d603b28 _CF_forwarding_prep_0 + 120
5 MyApp 0x000000010c869317 -[SFOAuthCredentials keyMacForService:] + 84
6 MyApp 0x000000010c8696b8 -[SFOAuthCredentials updateTokenEncryption] + 210
7 MyApp 0x000000010c8673ee -[SFOAuthCredentials initWithIdentifier:clientId:encrypted:] + 211
8 MyApp 0x000000010c84102c -[SFUserAccount initWithIdentifier:] + 197
9 MyApp 0x000000010c85f32d -[SFUserAccountManager createUserAccount] + 91
10 MyApp 0x000000010c831b41 -[SFAuthenticationManager loginWithCompletion:failure:account:] + 284
11 MyApp 0x000000010c831a0b -[SFAuthenticationManager loginWithCompletion:failure:] + 53
12 MyApp 0x000000010c60440c -[MyAuthenticationManager loginWithCompletion:failure:] + 124
13 MyApp 0x000000010c5dc58f _TFC18MyApp11AppDelegate5loginfS0_FT_T_ + 911
14 MyApp 0x000000010c5dfdc4 _TFC18MyApp25LandingPageViewController17loginButtonTappedfS0_FPSs9AnyObject_T_ + 68
15 MyApp 0x000000010c5dfe16 _TToFC18MyApp25LandingPageViewController17loginButtonTappedfS0_FPSs9AnyObject_T_ + 54
16 UIKit 0x000000010e1af1fa -[UIApplication sendAction:to:from:forEvent:] + 92
17 UIKit 0x000000010e313504 -[UIControl sendAction:to:forEvent:] + 67
18 UIKit 0x000000010e3137d0 -[UIControl _sendActionsForEvents:withEvent:] + 311
19 UIKit 0x000000010e312906 -[UIControl touchesEnded:withEvent:] + 601
20 UIKit 0x000000010e219aa3 -[UIWindow _sendTouchesForEvent:] + 835
21 UIKit 0x000000010e21a691 -[UIWindow sendEvent:] + 865
22 UIKit 0x000000010e1cc752 -[UIApplication sendEvent:] + 263
23 UIKit 0x000000010e1a7fcc _UIApplicationHandleEventQueue + 6693
24 CoreFoundation 0x000000010d5da0a1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
25 CoreFoundation 0x000000010d5cffcc __CFRunLoopDoSources0 + 556
26 CoreFoundation 0x000000010d5cf483 __CFRunLoopRun + 867
27 CoreFoundation 0x000000010d5cee98 CFRunLoopRunSpecific + 488
28 GraphicsServices 0x0000000113e46ad2 GSEventRunModal + 161
29 UIKit 0x000000010e1ad676 UIApplicationMain + 171
30 MyApp 0x000000010c5ddd8d main + 109
31 libdyld.dylib 0x00000001107a592d start + 1
32 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
SF SDK 有一个名为 UIDevice+SFHardware.h 的类别。在这个类别中有一个方法叫做 'macaddress'。很明显它没有正确阅读这个类别。但为什么?正如您从堆栈跟踪中看到的那样,它正在正确读取 SF SDK 中的其他文件。
我尝试了很多方法来让它工作。例如,这个:iOS - UUID generation throwing a strange exception but with UIDevice+SFHardware.h. I tried this: https://developer.salesforce.com/forums/?id=906F00000009CBvIAM。我再次完全重建项目以检查我的工作。
我不需要将这个文件添加到我的桥中,因为这个 UIDevice+SFHardware.h 只能从 ObjC 项目中的 SF SDK 访问。
不过我一定是做错了什么。任何帮助将不胜感激。
我刚刚解决了这个问题。
在您的项目 > 构建设置 > 其他链接器标志中添加: -ObjC -all_load
我的 SalesforceSDK 在我的 Pod 项目中。如果您这样做,请在您的 SalesforceMobileSDK-iOS 项目中设置这些标志。如果不是,Salesforce SDK 在何处编译。
事实证明这是多种因素的结合。首先,我在 Swift 项目和 Objc 项目中都缺少 -ObjC 链接器标志。感谢 DarthVadar123451 指出这一点。但我也意识到我缺少两个库:libz.dylib 和 libxml2.dylib。添加后,一切正常。我希望能帮助 运行 遇到同样问题的任何人。