Swift4集成Facebook Login SDK遇Type 'Any'无下标成员错误求解
Swift4环境下Facebook Login SDK获取用户邮箱时,出现"Type 'Any' has no subscript members"错误的解决方法
问题描述
我是开发新手,正在应用中集成Facebook Login SDK,已完成基础集成,现需获取用户邮箱。参照Swift3教程编写了如下fetchProfile函数:
func fetchProfile() { print("Fetch Profile") let parameters: [String : Any] = ["fields" : "email, first_name, last_name, picture.type(large)"] FBSDKGraphRequest(graphPath: "me", parameters: parameters).start(completionHandler: { (connection, result, error) -> Void in if error != nil { print(error!) return } if let email = result["email"] as? String { print(email) } }) }
但当前使用Swift4环境,代码中if let email = result["email"] as? String处提示“Type 'Any' has no subscript members”错误,请问是否因Swift版本差异导致?该如何解决?
解决方法
1. 错误原因
没错,这确实是Swift版本差异带来的问题!Swift 4对类型安全的要求比Swift 3更严格:在Swift 3中,FBSDKGraphRequest回调里的result参数虽然声明为Any?,但编译器允许你直接尝试用下标访问;但到了Swift 4,必须先明确将result转换为字典类型([String: Any]),才能使用下标取值。
2. 修改后的代码
你需要先把result安全转换为[String: Any]类型,再从中提取邮箱等字段。这里推荐用guard语句做安全校验,避免强制解包带来的崩溃:
func fetchProfile() { print("Fetch Profile") let parameters: [String : Any] = ["fields" : "email, first_name, last_name, picture.type(large)"] FBSDKGraphRequest(graphPath: "me", parameters: parameters).start(completionHandler: { (connection, result, error) -> Void in // 先处理错误 if let error = error { print("获取用户信息失败:\(error.localizedDescription)") return } // 安全转换result为字典类型 guard let userProfile = result as? [String: Any] else { print("无法解析用户数据") return } // 提取邮箱 if let email = userProfile["email"] as? String { print("用户邮箱:\(email)") } // 顺便提取其他字段(可选) if let firstName = userProfile["first_name"] as? String { print("用户名:\(firstName)") } if let lastName = userProfile["last_name"] as? String { print("用户姓:\(lastName)") } }) }
3. 额外注意事项
除了代码修改,还要确保你已经完成了两个关键配置:
- 在Facebook开发者后台的应用设置中,已经开启了
email权限的申请; - 在调用Facebook登录时,必须明确请求
email权限(不能只请求public_profile),示例代码如下:
let loginManager = FBSDKLoginManager() // 必须包含"email"权限,否则无法获取邮箱 loginManager.logIn(withReadPermissions: ["public_profile", "email"], from: self) { (loginResult, error) in guard error == nil, let result = loginResult, !result.isCancelled else { print("登录失败或用户取消") return } // 登录成功后再调用fetchProfile获取用户信息 self.fetchProfile() }
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

