Facebook SDK error for subscript members [duplicate] - ios

This question already has answers here:
Type 'Any?' has no subscript members [duplicate]
(2 answers)
Closed 6 years ago.
I am using Facebook SDK for login and fetching data at my end but unable to solve the issue I am facing challenges related to syntax
func fetchProfile() {
let parameters = ["fields": "email, first_name, last_name, picture.type(large)"]
FBSDKGraphRequest(graphPath: "me", parameters: parameters).start(completionHandler: { (connection, user, requestError) -> Void in
if requestError != nil {
print(requestError)
return
}
var email = user["email"] as? String
let firstName = user["first_name"] as? String
let lastName = user["last_name"] as? String
self.nameLabel.text = "\(firstName!) \(lastName!)"
var pictureUrl = ""
if let picture = user["picture"] as? NSDictionary, let data = picture["data"] as? NSDictionary, let url = data["url"] as? String {
pictureUrl = url
}
})
}
In the line var email = user["email"] as ? String i getting error as type any? has no transcript.

Try this:
if let dataDict = user as? [String:AnyObject] {
var email = dataDict["email"] as? String
let firstName = dataDict["first_name"] as? String
let lastName = dataDict["last_name"] as? String
//self.nameLabel.text = "\(firstName!) \(lastName!)"
var pictureUrl = ""
if let picture = dataDict["picture"] as? [String:AnyObject], let data = picture["data"] as? [String:AnyObject], let url = data["url"] as? String {
pictureUrl = url
}
}
You need to convert the user type Any to type Dictionary [String:AnyObject], then only you can use subscripts to extract value from it.

Related

How to get the stream key of a particular page of facebook using graph api in swift?

I have referred this link.
https://developers.facebook.com/docs/pages/getting-started but could not get answer.
I need "134902671......?s_bl=1&s_sc=134902691.....&s_sw=0&s_vt=api-s&a=AbyURQDWoQ-jNWNr" this stream key of page.
func getPageDetail(dict: [String:Any]) {
var request: GraphRequest?
let accessToken = AccessToken.current?.tokenString
print("{accessToken-\(accessToken)-}")
let params = ["access_token" : dict["access_token"] as! String,
"page_id" : dict["id"] as! String
]
request = GraphRequest.init(graphPath: "/me/live_videos?access_token=\(accessToken!)", parameters: params, httpMethod: HTTPMethod(rawValue: "POST"))
request?.start(completionHandler: { (_, result, _) in
print("result-........\(result)-")
let dict = result as! NSDictionary
let id = dict.value(forKey: "id") as! String
let streamUrlStr = dict.value(forKey: "stream_url") as! String
let lastCom = streamUrlStr.components(separatedBy: "/")
let finalStr = lastCom.last!
print(finalStr)
})
}
The finalStr which I am getting here does not match the stream key which is there in the page.

Read response from Facebook Graph Request in Swift 4

I'm trying to add a Facebook friend list to my Swift iOS app using the Graph API.
I'm struggling to work out how to actually access the data that's being send back from Facebook.
The response I get looks like this:
success(FacebookCore.GraphResponse(rawResponse: Optional({
"first_name" = Jamie;
id = 1626917907360895;
"last_name" = McAllister;
name = "Jamie McAllister";
picture = {
data = {
height = 50;
"is_silhouette" = 0;
url = "https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/12994335_1101318013254223_4481895970110564364_n.jpg?oh=d10209f113213981e4417e7f6f3f82d8&oe=5A91F135";
width = 50;
};
};
})))
My graph Request is just /me for now as I'm the only registered user. But all the fields in the response are what I will be requesting from the friends list
The graph request looks like this:
var graph = GraphRequest.init(graphPath: "me")
graph.parameters = ["fields": "id, first_name, last_name, middle_name, name, email, picture"]
graph.start({ (response, data) in
print("======GRAPH=====")
print(data)
})
So, I want to be able to take the GraphResponse, make it an Array and assign it to a variable. I am completely stumped by this one.
Hope this Helps
Swift 4.2
func getFbId(){
if(AccessToken.current != nil){
let req = GraphRequest(graphPath: "me", parameters: ["fields": "email,first_name,last_name,gender,picture"], accessToken: AccessToken.current, httpMethod: GraphRequestHTTPMethod(rawValue: "GET")!)
req.start({ (connection, result) in
switch result {
case .failed(let error):
print(error)
case .success(let graphResponse):
if let responseDictionary = graphResponse.dictionaryValue {
print(responseDictionary)
let firstNameFB = responseDictionary["first_name"] as? String
let lastNameFB = responseDictionary["last_name"] as? String
let socialIdFB = responseDictionary["id"] as? String
let genderFB = responseDictionary["gender"] as? String
let pictureUrlFB = responseDictionary["picture"] as? [String:Any]
let photoData = pictureUrlFB!["data"] as? [String:Any]
let photoUrl = photoData!["url"] as? String
print(firstNameFB, lastNameFB, socialIdFB, genderFB, photoUrl)
}
}
})
}
}
The Graph request start completion block has changed to requiring 3 arguments instead of 2.
So you will have something like this (NOTICE THERE ARE NOW 3 ITEMS PASSED IN THE START BLOCK [connection, result, and error]):
let params = ["fields" : "email, first_name, id, picture"]
let graphRequest = GraphRequest(graphPath: "me", parameters: params)
graphRequest.start{
(connection, result, error in
if error == nil {
if let responseDictionary = result as? NSDictionary {
UserProfile.userName = responseDictionary["first_name"] as? String ?? "User"
UserProfile.userID = responseDictionary["id"] as! String
var pictureUrl = ""
if let picture = responseDictionary["picture"] as? NSDictionary, let data = picture["data"] as? NSDictionary, let url = data["url"] as? String {
pictureUrl = url
}
}
}else{
print("error in graph request:", error)
}
To read response from Facebook Graph Request use the below line of codes
let info = data as! [String : AnyObject]
if info["name"] as? String != nil {
self.usernameLbl.text = info["name"] as! String
}
Hope this will help you

How to return a JSON string embedded in a dictionary using Alamofire/ ObjectMapper?

I'm having issues trying to access a string inside of a JSON dictionary, Here is the JSON data, the string I'm trying to access is the "link" value :
channels = (
{
social = {
facebook = {
"facebook_id" = 47360808996;
link = "https://www.facebook.com/CBS";
};
twitter = {
link = "https://twitter.com/CBS";
"twitter_id" = 97739866;
};
};
}
);
Here is the custom objects I created which keeps giving me an error
" Type '(key: String, value: AnyObject)' has no subscript members"
class SocialInfo: NSObject, Mappable {
var facebook: String?
var facebookDict: String?
required init?(map: Map) {
}
func mapping(map: Map) {
///transforms string to dictionary [string: anyobject] - only used for specific JSON data name: (facebook) - (link)
let facebookTransform = TransformOf<String, [String: AnyObject]> (fromJSON: { (value: [String: AnyObject]?) -> String? in
if let value = value {
for dict in value {
if let social = dict["social"] as? NSDictionary {
if let fb = social["facebook"] as? [String: AnyObject]{
if let fbLink = fb["link"] as? String{
return fbLink
}
}
}
}
}
return nil
}, toJSON: { (value: String?) -> [String: AnyObject]? in
return nil
})
facebookDict <- (map["channels"], facebookTransform)
facebook <- map["link"]
}
}
Here is my JSON call function to get info:
func getSocialInfo (_ completion: (([SocialInfo]) -> Void)?) {
Alamofire.request("\(baseURL)/\(apiKey)/show/950", method: .get, encoding: JSONEncoding.default).responseArray { (response: DataResponse<[SocialInfo]>) in
if let channelsResponse = response.result.value {
completion?(channelsResponse)
}
}
}
For reference I recreated this from a working project using NSURLSession the below code works:
if let channels = jsonResult["channels"] as? [[String:AnyObject]], !channels.isEmpty {
let channel = channels[0] // now the compiler knows it's [String:AnyObject]
let social = channel["social"] as? NSDictionary
let facebookDict = social!["facebook"] as? [String:AnyObject]
let facebook = nullToNil(facebookDict!["link"]) as? String ?? "N/A"
let twitterDict = social!["twitter"] as? [String:AnyObject]
let twitter = nullToNil(twitterDict!["link"]) as? String ?? "N/A"
I will assume you use Swift 3, as Swift 2 is deprecated.
You should avoid NSDictionary and AnyObject when parsing JSON in Swift 3. Simply use [String: Any] everywhere instead.

How to parse this JSON from swift 3 facebook graph request

I am using a graph request to get a json using this code:
nextrequest.start({ (response: HTTPURLResponse?, result: Any?) in
print(result)
})
this is the json result below and I have no idea how to access the the data inside such as gender, id and name...
Optional(FacebookCore.GraphRequestResult<FacebookCore.GraphRequest>.success(FacebookCore.GraphResponse(rawResponse: Optional({
gender = male;
id = 1128614937219535;
name = "Rayan Slim";
picture = {
data = {
height = 320;
"is_silhouette" = 0;
url = "https://scontent.xx.fbcdn.net/v/t1.0-1/p320x320/12541113_961418627272501_5451131278168499090_n.jpg?oh=47433bc236ce63ce1c07b92499087f29&oe=586A406A";
width = 320;
};
};
}))))
any help would be greatly appreciated!!!!
After permission has been granted here's the function that works.
if AccessToken.current != nil {
GraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start({ (urlResponse, requestResult) in
switch requestResult {
case .Success(let response):
if let responseDictionary = response.dictionaryValue {
let email = responseDictionary["email"] as? String
print(email)
let first = responseDictionary["name"] as? String
print(first)
if let picture = responseDictionary["picture"] as? NSDictionary {
if let data = picture["data"] as? NSDictionary{
if let profilePicture = data["url"] as? String {
print(profilePicture)
}
}
}
}
case .Failed(let error):
print(error)
}
})
}
This is tested and working in Swift 3, using the Facebook SDK for Swift
let pictureRequest = GraphRequest(graphPath: "me/picture?type=large&redirect=false", parameters: [:])
pictureRequest.start{
(urlResponse, requestResult) in
switch requestResult {
case .failed(let error):
print("error in graph request:", error)
break
case .success(let graphResponse):
if let responseDictionary = graphResponse.dictionaryValue {
print(responseDictionary)
var dict: NSDictionary!
dict = responseDictionary["data"] as! NSDictionary
print(dict)
print(dict["url"])
}
}
}
if let userDataDict = result as? NSDictionary {
self.first_name = userDataDict["first_name"] as? String
self.id = userDataDict["id"] as? String
self.last_name = userDataDict["last_name"] as? String
let pictDict = userDataDict["picture"] as? NSDictionary
let pictureUrl = pictDict?["data"] as? NSDictionary
self.pictureUrl = pictureUrl?["url"] as? String
}
do like
nextrequest.start({ (response: HTTPURLResponse?, result: Any?) in
print(result)
if let userData = result as? [NSObject: Any]
{
if let name = userData["name"] as? String
{
print(name)
}
if let picture = userData["picture"] as? [NSObject: Any] {
if let data = picture["data"] as? [NSObject: Any] {
if let profilePictureURL = data["url"] as? String {
// Now add the data to the UI elements
print (profilePictureURL)
}
}
}
}
})
Make use of some JSON parser, maybe Unbox that makes it easier to handle JSON. This code is not tested, but it is an outline of how you could do it. It is always code to store data in a struct instead of using dictionaries.
typealias JSON = [String: Any]
protocol Model {
init?(json: JSON)
}
func getDataFromFacebook() {
...
nextrequest.start {
(response: HTTPURLResponse?, result: Any?) in
self.handleFacebookResult(result)
}
}
func handleFacebookResult(_ result: Any?) {
guard
let json = result as? JSON,
let person = Person(json: json)
else { return }
//do something with person! :)
}
struct Person: Model {
let name: String
let gender: String
let picture: Picture
init?(json: JSON) {
guard
let name = json["name"] as? String,
let gender = json["gender"] as? String,
let pictureJson = json["picture.data"] as? JSON, // "picture.data" possible when using 'Unbox'
let picture = Picture(json: pictureJson)
else { return nil }
self.name = name
self.gender = gender
self.picture = picture
}
}
struct Picture: Model {
let height: Int // Or maybe float...?
let width: Int // Or maybe float...?
let url: String
init?(json: JSON) {
guard
let height = json["height"] as? Int,
let width = json["width"] as? Int,
let url = json["url"] as? String
else { return nil }
self.height = height
self.width = width
self.url
}
}

Type 'Any?' has no subscript members [duplicate]

This question already has answers here:
Type 'Any' has no subscript members (firebase)
(2 answers)
Closed 5 years ago.
I am trying to retrieve email id after fb login in my app. However I am getting an error when i try to get the value from result.
The error is:Type 'Any?' has no subscript members.
func fetchProfile()
{
print("Fetch Profile")
let parameters = ["fields": "email, first_name, last_name, picture.type(large)"]
FBSDKGraphRequest(graphPath: "me", parameters: parameters).start { (connection, result, error) in
let email = result["email"] as? String //Type 'Any?' has no subscript members error occurs here.
}
}
change this
let email = result["email"] as? String
into
guard let resultNew = result as? [String:Any]
let email = resultNew["email"] as! String
full answer
let parameters = ["fields": "email, first_name, last_name, picture.type(large)"]
FBSDKGraphRequest(graphPath: "me", parameters: parameters).start { (connection, result, error) in
guard let resultNew = result as? [String:Any]
let email = resultNew["email"] as! String
}
For Swift 3.
change this-->
let email = result["email"] as? String
Into -->
if let fbemail = (result as AnyObject)["email"]! as? String
{
print(fbemail)
}

Resources