问题
I am trying to get only the Text, Username, and later the profile image of the tweets returned by a twitter API call, using their reference: Twitter API: Search Tweets. I've gotten an authentic response, and can parse the JSON by Status, but the contents of each status seems to be in a format that is not JSON, as each "key" isn't in quotes and uses an equals sign to associate with it's value.
Does anyone know how I can take the 'status' object I end up with and pull any of the values out? Even just converting it into a string, and I can just use string parsing to pull it out. This is simply for a learning project and it does not need to be fancy.
Also, any explanation as to why the 'JSON' I'm looking at doesn't actually follow normal JSON format, would be helpful.
I'm using TwitterKit to make the request. I am fairly new to swift, and JSON parsing. Here is my code:
let client = TWTRAPIClient()
let statusesShowEndpoint = "https://api.twitter.com/1.1/search/tweets.json"
let params = ["q": "@formlabs", "result_type": "recent", "include_entities": "false", "count": "3"]
var clientError : NSError?
let request = client.urlRequest(withMethod: "GET", url: statusesShowEndpoint, parameters: params, error: &clientError)
client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
if connectionError != nil {
print("Error: \(String(describing: connectionError))")
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]
//print(json)
let statuses = json!["statuses"] as? [Any]
let status = statuses![0]
print(status)
} catch let jsonError as NSError {
print("json error: \(jsonError.localizedDescription)")
}
}
Here is output when I print out one status, which I can only seem to cast as Any. When I try to cast as a String, it comes back nil.
{
contributors = "<null>";
coordinates = "<null>";
"created_at" = "Thu Oct 26 21:22:50 +0000 2017";
"favorite_count" = 1;
favorited = 0;
geo = "<null>";
id = 923661218778247169;
"id_str" = 923661218778247169;
"in_reply_to_screen_name" = mesgreene;
"in_reply_to_status_id" = 923623395849367552;
"in_reply_to_status_id_str" = 923623395849367552;
"in_reply_to_user_id" = 71702948;
"in_reply_to_user_id_str" = 71702948;
"is_quote_status" = 0;
lang = en;
metadata = {
"iso_language_code" = en;
"result_type" = recent;
};
place = {
attributes = {
};
"bounding_box" = {
coordinates = (
(
(
"-117.282538",
"32.53962"
),
(
"-116.9274403",
"32.53962"
),
(
"-116.9274403",
"33.0804044"
),
(
"-117.282538",
"33.0804044"
)
)
);
type = Polygon;
};
"contained_within" = (
);
country = "United States";
"country_code" = US;
"full_name" = "San Diego, CA";
id = a592bd6ceb1319f7;
name = "San Diego";
"place_type" = city;
url = "https://api.twitter.com/1.1/geo/id/a592bd6ceb1319f7.json";
};
"retweet_count" = 0;
retweeted = 0;
source = "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>";
text = "@mesgreene @HeroForgeMinis @formlabs Formlabs said I would have to apply a primer to it, then I could paint it with\U2026 ";
truncated = 1;
user = {
"contributors_enabled" = 0;
"created_at" = "Wed Jan 16 03:07:48 +0000 2013";
"default_profile" = 0;
"default_profile_image" = 0;
description = "Bridge Designer. Alternative Delivery Expert. ProjectWise Dude. Guru in all things BIM/CAD. And I moonlight as patient support for people with Crohn's / IBD";
entities = {
description = {
urls = (
);
};
url = {
urls = (
{
"display_url" = "/Zv8TKR";
"expanded_url" = "https:///Zv8TKR";
indices = (
0,
23
);
url = "https:///mOUvQ9iP7w";
}
);
};
};
"favourites_count" = 3530;
"follow_request_sent" = "<null>";
"followers_count" = 238;
following = "<null>";
"friends_count" = 232;
"geo_enabled" = 1;
"has_extended_profile" = 1;
id = 1093947408;
"id_str" = 1093947408;
"is_translation_enabled" = 0;
"is_translator" = 0;
lang = en;
"listed_count" = 29;
location = "San Diego, CA";
name = "SoCal BIM Guru";
notifications = "<null>";
"profile_background_color" = 000000;
"profile_background_image_url" = "http://abs.twimg.com/images/themes/theme1/bg.png";
"profile_background_image_url_https" = "https://abs.twimg.com/images/themes/theme1/bg.png";
"profile_background_tile" = 0;
"profile_banner_url" = "https://pbs.twimg.com/profile_banners/1093947408/1499732034";
"profile_image_url" = "http://pbs.twimg.com/profile_images/885923732178337792/qnWdWM_J_normal.jpg";
"profile_image_url_https" = "https://pbs.twimg.com/profile_images/885923732178337792/qnWdWM_J_normal.jpg";
"profile_link_color" = 1B95E0;
"profile_sidebar_border_color" = 000000;
"profile_sidebar_fill_color" = 000000;
"profile_text_color" = 000000;
"profile_use_background_image" = 0;
protected = 0;
"screen_name" = ReubenJStone;
"statuses_count" = 1304;
"time_zone" = "Pacific Time (US & Canada)";
"translator_type" = none;
url = "https:///mOUvQ9iP7w";
"utc_offset" = "-25200";
verified = 0;
};
}
回答1:
The correct answer is to use the new Codeable framework: https://medium.com/swiftly-swift/swift-4-decodable-beyond-the-basics-990cc48b7375
来源:https://stackoverflow.com/questions/46964712/parsing-twitter-api-search-response-in-swift-with-twitterkit