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 = "Twitter Web Client";
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;
};
}
The correct answer is to use the new Codeable framework: https://medium.com/swiftly-swift/swift-4-decodable-beyond-the-basics-990cc48b7375
So I have successfully declared some variables obtained by JsonDictionary, but keep on getting nil, here's my code when declaring the variables:
var userName : String!
var text : String!
var name : String!
var tweetID : [NSObject : String]!
var tweetIDStr : String!
var userLocation : String!
var UserImgURLStr : String?
var options : NSJSONReadingOptions!
init(jsonDataDictiony : [String : AnyObject])
{
self.text = jsonDataDictiony["text"] as! String
self.tweetIDStr = jsonDataDictiony["id_str"] as! String
//print(jsonDataDictiony)
if let userDictionary = jsonDataDictiony["user"] as? [String : AnyObject]
{
self.userName = userDictionary["screen_name"] as! String
self.userLocation = userDictionary["location"] as! String
self.name = userDictionary["name"] as! String
}
print(self.text)
print(self.userName)
print(self.userLocation)
print(self.tweetIDStr)
print("-")
}
func castStringToDictionary()
{
let jsonData : NSData = tweetIDStr.dataUsingEncoding(NSUTF8StringEncoding)!
self.tweetID = try! NSJSONSerialization.JSONObjectWithData(jsonData, options: options) as! [NSObject : String]
}
and this is the code when trying to call the function (different class):
var selectedTweet : Tweet!
var twitterNetworkController : NetworkController!
var theTweet = [Tweet]()
override func viewDidLoad()
{
super.viewDidLoad()
self.navigationItem.title = selectedTweet.name + "'s tweet"
twitterNetworkController.fetchTweetID(selectedTweet.tweetID!)
//it gets a nil value here ^
{
(results, error) in
if error == nil
{
self.theTweet = results!
self.selectedFeedTableView.reloadData()
}
else
{
print(error)
}
}
}
Here's the console print:
["in_reply_to_user_id": , "possibly_sensitive_appealable": 0, "favorite_count": 0, "possibly_sensitive": 0, "in_reply_to_status_id": , "in_reply_to_user_id_str": , "lang": en, "favorited": 0, "id": 736420019152637952, "text": 🐐 (at Sate Tegal Marem) — url, "coordinates": , "geo": , "user": {
"contributors_enabled" = 0;
"created_at" = "Mon May 21 09:06:46 +0000 2012";
"default_profile" = 0;
"default_profile_image" = 0;
description = "\Uad1c\Ucc2e\Uc744\Ud150\Ub370 \U2b50";
entities = {
description = {
urls = (
);
};
};
"favourites_count" = 11;
"follow_request_sent" = 0;
"followers_count" = 155;
following = 1;
"friends_count" = 134;
"geo_enabled" = 0;
"has_extended_profile" = 0;
id = 586390966;
"id_str" = 586390966;
"is_translation_enabled" = 0;
"is_translator" = 0;
lang = en;
"listed_count" = 0;
location = "";
name = "tania.";
notifications = 0;
"profile_background_color" = B4DEBA;
"profile_background_image_url" = img url;
"profile_background_image_url_https" = img url;
"profile_background_tile" = 0;
"profile_banner_url" = banner url = img url;
"profile_image_url_https" = img url;
"profile_link_color" = 44A681;
"profile_sidebar_border_color" = FFFFFF;
"profile_sidebar_fill_color" = FFFFFF;
"profile_text_color" = 333333;
"profile_use_background_image" = 1;
protected = 0;
"screen_name" = "tania_alice";
"statuses_count" = 2332;
"time_zone" = Jakarta;
url = "";
"utc_offset" = 25200;
verified = 0;
}, "id_str": 736420019152637952, "created_at": Sat May 28 04:53:09 +0000 2016,
I replaced all the urls since it gave error (my reputation is less than 10 and I cannot post urls)
I am facing this kind of error: 'PGTransactionViewController' has no member 'initTransactionForOrder'. Can anyone help me out to sort out it.
func Pay_btn_Action(sender:UIButton!) {
var mc: PGMerchantConfiguration = PGMerchantConfiguration.defaultConfiguration()
mc.checksumGenerationURL = "https://pguat.paytm.com/paytmchecksum/paytmCheckSumGenerator.jsp"
mc.checksumValidationURL = "https://pguat.paytm.com/paytmchecksum/paytmCheckSumVerify.jsp"
var orderDict: [NSObject : AnyObject] = NSMutableDictionary() as [NSObject : AnyObject]
orderDict["MID"] = "WorldP64425807474247"
orderDict["CHANNEL_ID"] = "WAP"
orderDict["INDUSTRY_TYPE_ID"] = "Retail"
orderDict["WEBSITE"] = "worldpressplg"
orderDict["TXN_AMOUNT"] = "1"
orderDict["ORDER_ID"] = PaymentView.generateOrderIDWithPrefix("")
orderDict["REQUEST_TYPE"] = "DEFAULT"
orderDict["CUST_ID"] = "1234567890"
var order: PGOrder = PGOrder(params: orderDict)
PGServerEnvironment.selectServerDialog(self.tbl_Payment, completionHandler: {(type: ServerType) -> Void in
var txnController: PGTransactionViewController = PGTransactionViewController.initTransactionForOrder(order)
if type != eServerTypeNone {
txnController.serverType = type
txnController.merchant = mc
txnController.delegate = self
self.showController(txnController)
}
})
}
I don't know this specific library, but in general, if this has been adapted to Swift from Objective-C, it should be something like this:
PGTransactionViewController(transactionForOrder: order)
I have solved all the queries.
func Pay_btn_Action(sender:UIButton!) {
//Step 1: Create a default merchant config object
let mc: PGMerchantConfiguration =
PGMerchantConfiguration.defaultConfiguration()
//Step 2: If you have your own checksum generation and validation url set this here. Otherwise use the default Paytm urls
mc.checksumGenerationURL = "https://pguat.paytm.com/paytmchecksum/paytmCheckSumGenerator.jsp"
mc.checksumValidationURL = "https://pguat.paytm.com/paytmchecksum/paytmCheckSumVerify.jsp"
//Step 3: Create the order with whatever params you want to add. But make sure that you include the merchant mandatory params
var orderDict: [NSObject : AnyObject] = NSMutableDictionary() as [NSObject : AnyObject]
orderDict["MID"] = "WorldP64425807474247"
//Merchant configuration in the order object
orderDict["CHANNEL_ID"] = "WAP"
orderDict["INDUSTRY_TYPE_ID"] = "Retail"
orderDict["WEBSITE"] = "worldpressplg"
//Order configuration in the order object
orderDict["TXN_AMOUNT"] = "5"
orderDict["ORDER_ID"] = ViewController.generateOrderIDWithPrefix("")
orderDict["REQUEST_TYPE"] = "DEFAULT"
orderDict["CUST_ID"] = "1234567890"
let order: PGOrder = PGOrder(params: orderDict)
//Step 4: Choose the PG server. In your production build dont call selectServerDialog. Just create a instance of the
//PGTransactionViewController and set the serverType to eServerTypeProduction
PGServerEnvironment.selectServerDialog(self.view, completionHandler: {(type: ServerType) -> Void in
let txnController = PGTransactionViewController.init(transactionForOrder: order)
if type != eServerTypeNone {
txnController.serverType = type
txnController.merchant = mc
txnController.delegate = self
self.showController(txnController)
}
})
}
If anyone wants the Swift 2.1 Paytm wallet Integration code into their iOS app can download the whole project from here.
link
I am having some troubles with some json data. I'm making a weather app and most of the information I parsed works but the weather
this is the council output for the json data as a whole this is the section im having troubles with
the full output of json
{
base = stations;
clouds = {
all = 90;
};
cod = 200;
coord = {
lat = "39.74";
lon = "-104.98";
};
dt = 1427305893;
id = 5419384;
main = {
humidity = 84;
pressure = 1022;
temp = "274.07";
"temp_max" = "275.35";
"temp_min" = "272.15";
};
name = Denver;
rain = {
1h = "0.25";
};
snow = {
1h = "0.17";
};
sys = {
country = US;
id = 532;
message = "0.07829999999999999";
sunrise = 1427288058;
sunset = 1427332632;
type = 1;
};
visibility = 4023;
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
},
{
description = snow;
icon = 13d;
id = 601;
main = Snow;
},
{
description = fog;
icon = 50d;
id = 741;
main = Fog;
},
{
description = mist;
icon = 50d;
id = 701;
main = Mist;
}
);
wind = {
deg = 20;
gust = "14.9";
speed = "12.9";
};
}
i also have it print the keys
[base, id, dt, snow, main, coord, sys, wind, weather, visibility, clouds, cod, name, rain]
I tried to save it as an array but when I set the arry[0] to a string it crashes
my code for the function
func populateLabels(weatherData: NSData){
var jsonError: NSError?
let json = NSJSONSerialization.JSONObjectWithData(weatherData, options: nil, error: &jsonError) as NSDictionary
println(json)
if let city = json["name"] as? String {
CityName.text = city
}
println(json.allKeys)
if let coord = json["coord"] as? NSDictionary {
if let longi = coord["lon"] as? Double {
long.text = String(format: "%.2f", longi)
}
if let lati = coord["lat"] as? Double {
lat.text = String(format: "%.2f", lati)
}
}
if let main = json["main"] as? NSDictionary {
if let temper = main["temp"] as? Double {
temp.text = String(format: "%.2f", temper)
}
}
If anyone knows how to get to the description that would be awesome
thanks js
I got it.. thanks for the help blacksquare, larme, chirag90
if let tasks = json["weather"] as? NSArray
{
if let task = tasks[0] as? NSDictionary
{
if let taskName = task["description"] as? NSString
{
println(taskName)
}
}
}
I'm trying to get the JSON from a website and parse it before putting it inside of an iOS view.
Here's my code;
func startConnection(){
let urlPath: String = "http://binaenaleyh.net/dusor/"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
connection.start()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.data.appendData(data)
}
func buttonAction(sender: UIButton!){
startConnection()
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var err: NSError
// throwing an error on the line below (can't figure out where the error message is)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
}
And this is the link for the JSON;
http://binaenaleyh.net/dusor/
What am I doing wrong here?
These two functions worked for me:
func getJSON(urlToRequest: String) -> NSData{
return NSData(contentsOfURL: NSURL(string: urlToRequest))
}
func parseJSON(inputData: NSData) -> NSDictionary{
var error: NSError?
var boardsDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(inputData, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
return boardsDictionary
}
UPDATE: Swift 4
// Asynchronous Http call to your api url, using URLSession:
URLSession.shared.dataTask(with: URL(string: "http://api.site.com/json")!) { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert to dictionary where keys are of type String, and values are of any type
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: Any]
// Access specific key with value of type String
let str = json["key"] as! String
} catch {
// Something went wrong
}
}
}.resume()
Here is how to do it with Swift 2 and NSURLSession:
// Asynchronous Http call to your api url, using NSURLSession:
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://api.site.com/json")!, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]
// Access specific key with value of type String
let str = json["key"] as! String
} catch {
// Something went wrong
}
}
}).resume()
This code works fine for me. Just init data property with data = NSMutableData() and write NSURLConnectionDelegate here class ViewController: UIViewController, NSURLConnectionDelegate
import UIKit
class ViewController: UIViewController, NSURLConnectionDelegate {
#lazy var data = NSMutableData()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
startConnection()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func startConnection(){
let urlPath: String = "http://binaenaleyh.net/dusor/"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
connection.start()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.data.appendData(data)
}
func buttonAction(sender: UIButton!){
startConnection()
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var err: NSError
// throwing an error on the line below (can't figure out where the error message is)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println(jsonResult)
}
}
here is output:
{
"ders sayisi" = 15;
dersler = (
{
0 = "2013-2014";
1 = BAHAR;
10 = TeacherHold;
11 = 2;
12 = "";
2 = 2;
3 = "CEE 102";
4 = "Logic Circuits";
5 = 3;
6 = "6.00";
7 = "YRD.DO\U00c7.DR.INDRIT MYDERRIZI";
8 = 0;
9 = IA;
},
{
0 = "2013-2014";
1 = BAHAR;
10 = TeacherHold;
11 = 1;
12 = "";
2 = 2;
3 = "CIP 102";
4 = "Civic Involment Projects";
5 = 0;
6 = "2.00";
7 = "SE\U00c7\U0130L AVCI/BA\U015eAK CANSU AK\U00c7EL\U0130K/\U00c7A\U011eLA UNGUN";
8 = 0;
9 = P;
},
{
0 = "2013-2014";
1 = BAHAR;
10 = TeacherHold;
11 = 2;
12 = "";
2 = 2;
3 = "COME 108";
4 = "Algorithms and Programming II";
5 = 3;
6 = "6.00";
7 = "\U00d6\U011eR.G\U00d6R.DR.B\U0130RSEN G\U00dcLDEN \U00d6ZDEM\U0130R";
8 = 41;
9 = C;
},
{
0 = "2013-2014";
1 = BAHAR;
10 = TeacherHold;
11 = 1;
12 = "";
2 = 2;
3 = "COME 335";
4 = "Mobile Application Development";
5 = 3;
6 = "5.00";
7 = "\U00d6\U011eR.G\U00d6R.OZAN UYSAL";
8 = TeacherHold;
9 = TeacherHold;
},
{
0 = "2013-2014";
1 = BAHAR;
10 = TeacherHold;
11 = 1;
12 = "";
2 = 2;
3 = "ENG 112";
4 = "Advanced English For Engineering and Natural Sciences I";
5 = 2;
6 = "3.00";
7 = "OKT.ERIC BEECHER";
8 = 48;
9 = F;
},
{
0 = "2013-2014";
1 = BAHAR;
10 = TeacherHold;
11 = 1;
12 = "";
2 = 2;
3 = "PHYS 102";
4 = "Physics II";
5 = 4;
6 = "5.00";
7 = "YRD.DO\U00c7.DR.\U00d6ZG\U00dcL KURTULU\U015e \U00d6ZT\U00dcRK";
8 = "-1";
9 = F;
},
{
0 = "2013-2014";
1 = BAHAR;
10 = TeacherHold;
11 = 2;
12 = "";
2 = 2;
3 = "T\U00dcRK 102";
4 = "T\U00fcrk Dili II";
5 = 2;
6 = "2.00";
7 = "\U00d6\U011eR.G\U00d6R.\U015eER\U0130FE GEZG\U0130N";
8 = 10;
9 = F;
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 2;
12 = "";
2 = 1;
3 = "CHEM 101";
4 = Chemistry;
5 = 3;
6 = "5.00";
7 = "YRD.DO\U00c7.DR.AY\U015eEN TULPAR";
8 = TeacherHold;
9 = F;
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 1;
12 = "";
2 = 1;
3 = "CIP 101";
4 = "Civic Involment Projects";
5 = 0;
6 = "1.00";
7 = "YRD.DO\U00c7.DR.FATMA G\U00dcL AYGEN/Staff CIP1/SE\U00c7\U0130L AVCI/D\U0130LAYDA EM\U0130R/BA\U015eAK CANSU AK\U00c7EL\U0130K/\U00c7A\U011eLA UNGUN";
8 = TeacherHold;
9 = P;
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 3;
12 = "";
2 = 1;
3 = "COME 107";
4 = "Algorithms and Programming I";
5 = 4;
6 = "5.00";
7 = "PROF.DR.M\U0130TAT UYSAL";
8 = TeacherHold;
9 = "C+";
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 2;
12 = "";
2 = 1;
3 = "ENG 101";
4 = "Advanced English";
5 = 2;
6 = "3.00";
7 = "OKT.EZG\U0130 ARGUN";
8 = TeacherHold;
9 = B;
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 1;
12 = "";
2 = 1;
3 = "IUL 100";
4 = "Introduction to University Life";
5 = 0;
6 = "1.00";
7 = "YRD.DO\U00c7.DR.FATMA G\U00dcL AYGEN";
8 = TeacherHold;
9 = F;
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 2;
12 = "";
2 = 1;
3 = "MATH 111";
4 = "Calculus I";
5 = 4;
6 = "5.00";
7 = "DO\U00c7.DR.G\U00dcRSEL YE\U015e\U0130LOT";
8 = TeacherHold;
9 = F;
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 4;
12 = "";
2 = 1;
3 = "PHYS 101";
4 = "Physics I [CNE]";
5 = 4;
6 = "5.00";
7 = "YRD.DO\U00c7.DR.AR\U0130F \U00d6ZBAY";
8 = TeacherHold;
9 = F;
},
{
0 = "2013-2014";
1 = "G\U00dcZ";
10 = TeacherHold;
11 = 9;
12 = "";
2 = 1;
3 = "T\U00dcRK 101";
4 = "T\U00fcrk Dili I [CNE]";
5 = 2;
6 = "2.00";
7 = "\U00d6\U011eR.G\U00d6R.ARZU AYG\U00dcN";
8 = TeacherHold;
9 = F;
}
);
}
If the original JSON is an array, try this.
func parseJSON(inputData: NSData) -> Array<NSDictionary>{
var error: NSError?
var boardsDictionary = NSJSONSerialization.JSONObjectWithData(inputData, options: NSJSONReadingOptions.MutableContainers, error: &error) as Array<NSDictionary>
return boardsDictionary
}
The example below sends a request to fetch stock information - it's a bit more comprehensive, but has more cleanup and structure:
import Foundation
private let kSNStockInfoFetchRequestPath:String = "http://dev.markitondemand.com/Api/v2/Quote/json"
private func SNStockInfoFetchRequestURL(symbol:String) -> NSURL? {
if let components:NSURLComponents = NSURLComponents(string:kSNStockInfoFetchRequestPath) {
components.queryItems = [NSURLQueryItem(name:"symbol", value:symbol)]
return components.URL
}
return nil
}
private func SNStockInfoFetchRequestURLRequest(symbol:String) -> NSURLRequest? {
if let requestURL:NSURL = SNStockInfoFetchRequestURL(symbol) {
var request:NSMutableURLRequest = NSMutableURLRequest(URL:requestURL)
request.HTTPMethod = "GET"
return request
}
return nil
}
private func SNStockInfoFetchRequestParseData(receivedData:NSData, error:NSErrorPointer) -> NSDictionary? {
return NSJSONSerialization.JSONObjectWithData(receivedData, options:NSJSONReadingOptions.MutableContainers, error:error) as? NSDictionary
}
class SNStockInfoFetchRequest: NSObject,
NSURLConnectionDataDelegate
{
private let symbol:String
private (set) var fetching:Bool
private lazy var receivedData = NSMutableData()
init(symbol:String) {
self.symbol = symbol
self.fetching = false
}
func start() {
assert(!fetching, "Should not start a request that has already started!")
fetching = true
if let request:NSURLRequest = SNStockInfoFetchRequestURLRequest(symbol) {
var connection:NSURLConnection = NSURLConnection(request:request, delegate:self, startImmediately:true)!
connection.start()
}
}
// MARK: NSURLConnectionDataDelegate
func connection(connection:NSURLConnection, didReceiveData data:NSData) {
assert(fetching, "Should only receive data while activly fetching!")
self.receivedData.appendData(data)
}
func connectionDidFinishLoading(connection:NSURLConnection) {
var error:NSError?
if let result:NSDictionary = SNStockInfoFetchRequestParseData(receivedData, &error) {
println(result)
} else {
println(error)
}
}
}
We can now use the request as such:
let fetcher:SNStockInfoFetchRequest = SNStockInfoFetchRequest(symbol:"MSFT")
fetcher.start()
This should output the JSON in case of a success, or the error in case of a failure. Hope this helps! If you use the same structure, make sure to use a delegate to either return the parsed JSON (or even better, an immutable value object) or indicate a failure.
The answer of #david72 worked perfectly for me. So here's the same in Swift 3 and URLSession for your convenience. Also with some added error printing for easier debugging.
func getHttpData(urlAddress : String)
{
// Asynchronous Http call to your api url, using NSURLSession:
guard let url = URL(string: urlAddress) else
{
print("Url conversion issue.")
return
}
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
print(json)
// Access specific key with value of type String
// let str = json["key"] as! String
} catch {
print(error)
// Something went wrong
}
}
else if error != nil
{
print(error)
}
}).resume()
}
//
// ViewController.swift
// Test2
//
// Created by fingent on 11/08/15.
// Copyright (c) 2015 fingent. All rights reserved.
//
import UIKit
class ViewController: UIViewController,NSURLConnectionDelegate
{
lazy var data = NSMutableData()
#IBAction func t1(sender: AnyObject) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
startConnection()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startConnection(){
let urlPath: String = "https://api.github.com/users/mralexgray"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
connection.start()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.data.appendData(data)
}
func buttonAction(sender: UIButton!){
startConnection()
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var err: NSError
// throwing an error on the line below (can't figure out where the error message is)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println(jsonResult)
}
}
Here is swift 3.1 code
URLSession.shared.dataTask(with: NSURL(string: "http://pastebin.com/raw/wgkJgazE")! as URL, completionHandler: { (data, response, error) -> Void in
// Check if data was received successfully
if error == nil && data != nil {
do {
// Convert NSData to Dictionary where keys are of type String, and values are of any type
let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:AnyObject]
// Access specific key with value of type String
let str = json["key"] as! String
} catch {
// Something went wrong
}
}
}).resume()
Request api REST-GET in iOS Swift
I present a very simple App where a rest service is consumed through the GET method and the information obtained is presented in our main view.
Note:
This project is built with CocoaPods, for more information go to https://cocoapods.org.
PodFile structure:
# Uncomment the next line to define a global platform for your project
# platform :ios, '8.0'
target 'ExampleRestApi' do
# Comment the next line if you don't want to use dynamic frameworks
#use_frameworks!
# Pods for ExampleRestApi
use_modular_headers!
pod 'Alamofire', '~> 5.0'
pod 'AFNetworking', '~> 2.6'
pod 'ORStackView', '~> 3.0'
end
Steps
HelperNetwork.swift: Copy HelperNetwork file, which contains the method to consume the service through Alamofire.
//
// HelperNetwork.swift
// ExampleRestApi
//
// Created by MacBook Pro on 20/11/20.
//
import Foundation
import Alamofire
public var URL_API = "https://icenparty.pythonanywhere.com/icenPartyWeb/api/v1/"
public var GET_STORE = "doStore"
public var METHOD_GET: HTTPMethod = .get
class HelperNetwork{
//Example get json for method GET
func doRequest(urlString : String,
parameters : Parameters,
method : HTTPMethod,
completion: #escaping (AFDataResponse <Any>)->()) {
let url = URL.init(string: URL_API + urlString)
AF.request(url!, method: method, parameters: parameters, encoding: URLEncoding.default, headers: nil).responseJSON {
response in completion(response)
}
}
}
BaseResponse.swift: Copy BaseResponse file, which contains the models corresponding to the information obtained in the service response.
//
// BaseResponse.swift
// ExampleRestApi
//
// Created by MacBook Pro on 20/11/20.
//
/*
BaseResponse is used to create all the models that
we need for the service response.
*/
import Foundation
public struct Store : Codable{
var pk: Int
var fields: Fields
}
public struct Fields : Codable {
var file_img_home: String
var file_img_2: String
var file_img_3: String
var title: String
var subTitle: String
var description: String
var value: Int
var material: String
var color: String
var sizes_list: String
var brand: String
}
public struct JSONResponseStore: Codable {
var success: Bool
var message: String
var stores : [Store]
}
ViewController.swift: In our viewController file, call our doRequest method
to which the necessary parameters are passed to obtain the json.
#IBOutlet weak var lblResponse: UILabel!
var helperNetwork = HelperNetwork()
/**
Get info from server for method GET
*/
func getJsonRequestGET(){
//Set text lbl
lblResponse.text = "Consultando información...."
//parameters for get , we need tag typeStore
let parameters: Parameters = [ "typeStore" : "Hombre",]
self.helperNetwork.doRequest(urlString: GET_STORE,
parameters: parameters,
method: METHOD_GET) { (response) -> () in
// do stuff with the result
switch response.result
{
case .success( _):
do {
//Decode data From model JSONResponseStore , can be changed to any model
let JSONData = try JSONDecoder().decode(JSONResponseStore.self, from: response.data!)
if(JSONData.success){
self.lblResponse.text = "Respuesta: \(JSONData.stores)"
}else{
self.lblResponse.text = "Respuesta: \(JSONData.message)"
}
} catch let jsonError {
self.lblResponse.text = "Respuesta: \(jsonError)"
}
case .failure(let error):
self.lblResponse.text = "Respuesta: \(error)"
}
}
}
I remain attentive to any concerns,
Cheers