我目前正在开发一个集成了Facebook的iOS应用程序,我在使用Swift进行调查时遇到了一些问题(使用ObjC我没有问题)。
问题是,当来自另一个APP(在这种情况下是WebBrowser中的FB)时,这是在appDelegate中执行的方法:
func application(
application: UIApplication,
openURL url: NSURL,
sourceApplication: NSString,
annotation: AnyObject)
-> Bool {
let appString : String = sourceApplication as String // Try to convert format => EXCEPTION
let appString : String = String(sourceApplication) // 'SSS' Suggestion: EXCEPTION
println(sourceApplication) // Try to print the value => EXCEPTION
return FBAppCall.handleOpenURL(url, sourceApplication:sourceApplication,
withSession:session) // With Parse => EXCEPTION
}
在该方法中,我遇到了'sourceApplication'参数的问题。我尝试使用它,我得到一个例外。我尝试转换它,另一个例外...甚至无法记录其值,因为它在访问其值时崩溃。将函数签名中的参数类型更改为String既不起作用。
这是我得到的错误:
EXEC_BAD_ACCESS
我已经能够追踪,直到我能读到它,这绝对是一个有价值的暗示:
ObjectiveC.NSString.__conversion (ObjectiveC.NSString)() -> Swift.String
这可能是iOS8的错误吗? 你们中的任何人都有这个问题和/或知道如何解决它?
答案 0 :(得分:1)
你犯了两个错误:
app Delegate的函数声明为func application(application: UIApplication!, openURL url: NSURL!, sourceApplication: String!, annotation: AnyObject!) -> Bool
:sourceApplication是一个可选的String值,而不是NSString。
由于sourceApplication是可选的,因此可能会返回 nil 值(在您的情况下返回 nil )。键入 nil 到字符串是不安全的,因此它会崩溃。
解决方案:
if let appString = sourceApplication {
println(appString as? String)
}
答案 1 :(得分:1)
这对我有用(使用FacebookSDK):
func application(application: UIApplication, openURL url: NSURL, sourceApplication: NSString?, annotation: AnyObject) -> Bool {
var wasHandled:Bool = FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication)
return wasHandled
}
答案 2 :(得分:0)
我不会在操场上看到这个。可能是你建议的iOS 8错误 但是为了尝试,你可以试试
let appString : String = String(sourceApplication)
答案 3 :(得分:0)
对于FB Messenger ,这是我在AppDelegate中更好地处理的方法。大多数想法都直接来自FB IOS documentation并移植到Swift。
为什么我觉得我应该写一个额外的回复?我有一些使用Swift的经验,但感觉我浪费了足够的时间试图获得正确的代码来做我的事情FB Messenger需要。希望原始代码对某人有用,只需要整合大量的零碎并节省一些时间。
注意:这不包括您想要/需要的所有AppDelegate生命周期方法,但希望它是一个良好的开端
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, FBSDKMessengerURLHandlerDelegate {
var window: UIWindow?
var messengerUrlHandler: FBSDKMessengerURLHandler?
var cancelContext : FBSDKMessengerURLHandlerCancelContext?
var composerContext : FBSDKMessengerURLHandlerOpenFromComposerContext?
var replyContext: FBSDKMessengerURLHandlerReplyContext?
// Facebook Messenger
enum MessengerShareMode : Int {
case MessengerShareModeCancel
case MessengerShareModeSend
case MessengerShareModeComposer
case MessengerShareModeReply
}
// shareMode holds state indicating which flow the user is in.
// Return the corresponding FBSDKMessengerContext based on that state.
var shareMode : MessengerShareMode?
/*
* Initialize the FB messenger handler and set self as the delegate.
*/
func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
YARAppearance.setAppearance()
let rootController = TabBarController()
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window!.rootViewController = rootController
self.window!.makeKeyAndVisible()
// Facebook messenger handling
self.messengerUrlHandler = FBSDKMessengerURLHandler()
if (self.messengerUrlHandler != nil) {
self.messengerUrlHandler!.delegate = self
}
return true
}
/*
* Handle the cancel context flow.
*/
func messengerURLHandler(messengerURLHandler: FBSDKMessengerURLHandler!,
didHandleCancelWithContext context: FBSDKMessengerURLHandlerCancelContext!) {
self.cancelContext = context
self.shareMode = .MessengerShareModeCancel
}
/*
* When people enter your app through the composer in Messenger,
* this delegate function will be called.
*/
func messengerURLHandler(messengerURLHandler: FBSDKMessengerURLHandler!,
didHandleOpenFromComposerWithContext context: FBSDKMessengerURLHandlerOpenFromComposerContext!) {
self.composerContext = context
self.shareMode = .MessengerShareModeComposer
}
/*
* When people enter your app through the "Reply" button on content
* this delegate function will be called.
*/
func messengerURLHandler(messengerURLHandler: FBSDKMessengerURLHandler!,
didHandleReplyWithContext context: FBSDKMessengerURLHandlerReplyContext!) {
self.replyContext = context
self.shareMode = .MessengerShareModeReply
}
/*
* Handle URL calls from external applications, particularly Messenger
*/
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
let wasHandled:Bool = self.messengerUrlHandler!.openURL(url, sourceApplication: sourceApplication)
return wasHandled
}
/*
* A way to access the context objects elsewhere
*/
func getContextForShareMode() -> FBSDKMessengerContext? {
// shareMode holds state indicating which flow the user is in.
// Return the corresponding FBSDKMessengerContext based on that state.
if (shareMode == .MessengerShareModeSend) {
// Force a send flow by returning a broadcast context.
return FBSDKMessengerBroadcastContext()
} else if (shareMode == .MessengerShareModeComposer) {
// Force the composer flow by returning the composer context.
return self.composerContext!
} else if (shareMode == .MessengerShareModeReply) {
// Force the reply flow by returning the reply context.
return self.replyContext!
}
return nil
}
}