Ramsay Ramsay - 4 months ago 24
iOS Question

Facebook get friends JSON response is invalid

I am developing an app for iOS using Xamarin Studio (C#) in Mac OS X. I want to get a list of the user's friends on Facebook, so I added Facebook's component from Xamarin's component store and made a request(code at the bottom). This is the response I get:

{
data = (
{
"first_name" = Dev;
id = 100001438778777;
"last_name" = Accu;
}
);
paging = {
next = "https://graph.facebook.com/v2.0/100005203000814/friends?fields=id,first_name,last_name&format=json&access_token=CAAK3hGOIm2ABANPUcr2QU1t8gqLNsZCJBrc8ZCZCqUSwHkX2f43VHarvc1ZABbjDrY7jIO0OT5ZBRBiZC1audQnIvxCsOu60y30iR84jVa56beNTptixj7AFqT92ZBGdyxDshFHHxkFDgCg9JyRZBYfqaGKkeJkuxJVUXDq8eR8ZCmRlslpOVSavQZC1hCcxOwdgFS2jWQdGZBFVSYTkrhkavfP&limit=5000&offset=5000&__after_id=enc_Aey-LjP59ZnmKMcZKcEr94tTUPIHIvWj9JnMwkIVSvxJ9RBYBqhBt3bGKlURY4SHBCDeH8BM_wSsqICzEFgKiZvh";
};
}


There is 2 problems with this response, it only includes 1 friend for some unknown reason, and the JSON is not valid, so ultimately parsing this fails. The following is the code I use to make the request:

var friendsRequest = await new FBRequest(FBSession.ActiveSession, "/me/friends?fields=id,first_name,last_name").StartAsync();
var friendsArray = friendsRequest.Result as MonoTouch.Foundation.NSMutableDictionary;
var response = FriendResponse.FromJson(friendsArray.ToString());

List<FacebookProfile> friends = new List<FacebookProfile>();
foreach (var friend in response.Data)
{
friends.Add(new FacebookProfile(friend.ID, friend.FirstName, friend.LastName));
}


And here is the parsing classes:

public class NextPage
{
public string Next { get; set; }
}

public class Friend
{
public string ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

public class FriendResponse
{
public List<Friend> Data { get; set; }
public NextPage Paging { get; set; }

public static FriendResponse FromJson(string json)
{
JsConfig.EmitLowercaseUnderscoreNames = true;
return JsonSerializer.DeserializeFromString<FriendResponse>(json);
}
}

Answer

The component is a 1:1 binding to the objective-c SDK. The response that Facebook returns is an NSDictionary underneath, and if you run ToString() on it, it will return the string representation of the NSDictionary which is totally different from a JSON string. What you have to do is serialize that NSDictionary object back into a JSON string. Here is an example of how to do this:

var friendsRequest = await new FBRequest(FBSession.ActiveSession, "/me/friends?fields=id,first_name,last_name").StartAsync();

// Convert back the object into a Json
NSError error;
var jsonData = NSJsonSerialization.Serialize (friendsRequest.Result, 0, out error);
var jsonString = (string) NSString.FromData (jsonData, NSStringEncoding.UTF8);
var response = FriendResponse.FromJson(jsonString);

"jsonString" will have the correct JSON string data representation this time.

Courtesy of Alex DeSoto. =)