JSON data keep on returning nil - json

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)

Related

How can I view this Json in tableView by id's

I'm trying to parse a Json data using Alamofire in my App. I get the results and show them in tableView. However, I need to view results by their id object in Json result. For example if id=4, I just need to show which include id=4 object data in tableView.
Here's my code try to work. And Json data as well:
Json data:
{
data = (
{
content = "harika!! nerdeydiniz bu zamana kadar";
createdAt = {
date = "2019-06-04 12:34:22.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 1;
};
rating = 4;
},
{
content = "bu kadar\U0131 da olmaz";
createdAt = {
date = "2019-06-04 18:04:02.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 1;
};
rating = 5;
},
{
content = "be\U011fendim";
createdAt = {
date = "2019-06-01 18:04:02.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 2;
};
rating = 4;
},
{
content = "tekrar istiyorum";
createdAt = {
date = "2019-06-03 18:04:02.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 2;
};
rating = 5;
},
{
content = "tarot inan\U0131lmazd\U0131 kahveyi de g\U00f6nderece\U011fim";
createdAt = {
date = "2019-06-11 18:04:02.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 2;
};
rating = 5;
},
{
content = "yorum tuttu";
createdAt = {
date = "2019-06-12 18:04:02.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 3;
};
rating = 4;
},
{
content = "ahsen ne yapt\U0131n ahsen";
createdAt = {
date = "2019-06-16 18:04:02.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 3;
};
rating = 4;
},
{
content = "gece gece heyecanlad\U0131m";
createdAt = {
date = "2019-05-25 18:06:24.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 4;
};
rating = 4;
},
{
content = "mutlu hissediyor";
createdAt = {
date = "2019-05-28 18:06:24.000000";
timezone = "Europe/Istanbul";
"timezone_type" = 3;
};
fortuneTeller = {
id = 4;
};
rating = 5;
}
);
error = 0;
message = Success;
}
var message: String?
var array = [getReviewsModel]()
var homeDict = NSDictionary()
func getReviewApi (completion: #escaping (Bool, String) -> ()) {
let url = BaseUrl + getReviewsUrl
if Reachability.isConnectedToNetwork() {
getDictDataFromServer(url: url, headers: [:], completion: { (dict) in
print (dict)
if let err = dict.value(forKey: "error")
{
let message = dict.value(forKey: "message") as? String
let error = err as! Bool
if !error {
let arr = dict.value(forKey: "data") as! NSArray
for i in 0..<arr.count {
let obj = getReviewsModel()
obj.homeDict(dict: arr[i] as! [String : Any])
self.array.append(obj)
//print(obj)
}
if (self.array.count == 0)
{
completion (false, "Yorum bulunamadı.")
return
}
completion (true, "Success")
}
else
{
completion (false, message!)
}
}
else
{
completion (false, internalServerMsg)
}
})
}
else
{
completion(false,noInternetMsg)
}
}
func setDataForCell (index: Int, cell: reviewTableViewCell){
let obj = array[index]
cell.setData(obj: obj)
}
func numberOfItemsInSection () -> Int {
return array.count
}
func fortuneTellerId (index: Int) -> Int {
let obj = array[index].id
return obj ?? 0
}
And class
var content: String?
var createdAt: String?
var rating: Double?
var id: Int?
func homeDict (dict:[String:Any]){
self.content = dict["content"] as? String ?? ""
self.createdAt = (dict["createdAt"] as? NSDictionary)?.value(forKey: "date") as? String ?? ""
self.rating = dict["rating"] as? Double
self.id = (dict["fortuneTeller"] as? NSDictionary)?.value(forKey: "id") as? Int ?? 0
}
}
Here is my tableView functions:
var viewModel_1 = DefaultFormViewModel()
var jsonDict = NSDictionary()
#IBOutlet weak var reviewDetailView: UIView!
#IBOutlet weak var reviewContentView: UIView!
#IBOutlet weak var reviewTableView: UITableView!
#IBAction func viewReviewsAction(_ sender: Any) {
reviewDetailView.isHidden = false
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel_1.numberOfItemsInSection()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? reviewTableViewCell
cell?.selectionStyle = .none
viewModel_1.setDataForCell(index: indexPath.row, cell: cell!)
return cell!
}
override func viewDidLoad() {
super.viewDidLoad()
reviewTableView.dataSource = self
reviewTableView.delegate = self
reviewTableView.separatorStyle = .none
showActivityIndicator()
viewModel_1.getReviewApi { (sucess, message) in
self.hideactivityIndicator()
if (sucess)
{
self.reviewTableView.reloadData()
}
else
{
Utility().displayAlert(title: "Title", message: message, control: ["OK"])
}
}
}

Error when decoding JSON - keyNotFound(CodingKeys

I am trying to parse JSON data over the network. Below you can see where the magic is happening.
func getBookingsForDate(date: String, completionHandler: #escaping ([String:String]) -> Void ){
struct bookings: Codable {
var bookieName : String
var bookieNumber: String
var booked: String
var bookingTime: String
private enum Codingkeys: String, CodingKey{
case bookieName
case bookieNumber
case booked
case bookingTime
}
}
let params = ["date":date]
let urlString = "http://mscissorss.pythonanywhere.com/getBookings/"
Alamofire.request(urlString, method: .get, parameters: params).responseJSON {
response in
switch response.result {
case .success(let JSON):
let decoder = JSONDecoder()
guard let _ = response.data else{
return
}
do {
let loginDetails = try decoder.decode(bookings.self, from: response.data!)
print(loginDetails)
} catch let err{
print(err)
}
//let bookings = JSON as! NSDictionary
//completionHandler(JSON)
/*
do {
let decoder = JSONDecoder()
let gitData = try decoder.decode(bookings.self, from: JSON)
print(gitData.bookieName)
} catch let err {
print("Err", err)
}
*/
break
case .failure(let error):
print(error)
}
}
}
Given the code i am getting the following error message:
keyNotFound(CodingKeys(stringValue: "bookieName", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"bookieName\", intValue: nil) (\"bookieName\").", underlyingError: nil))
And the JSON response that i am getting looks like this:
{
0 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "10:00";
};
1 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "10:30";
};
10 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "15:00";
};
11 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "15:30";
};
12 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "16:00";
};
13 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "16:30";
};
14 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "17:00";
};
15 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "17:30";
};
16 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "18:00";
};
2 = {
booked = false;
bookieName = "";
bookieNumber = "";
bookingTime = "11:00";
};
}
It is the first time i am decoding so if you have an answer please try to explain a bit to why i need to make the change that i need.
UPDATE
After changing the code to what #sh_khan and #vadian suggested it worked to parse it however i am still getting this error inside my parsed object:
["1": MagicS.(unknown context at 0x106932738).bookings(bookieName: "", bookieNumber: "", booked: "false", bookingTime: "10:30"),
"0": MagicS.(unknown context at 0x106932738).bookings(bookieName: "", bookieNumber: "", booked: "false", bookingTime: "10:00"),
Also, if i want to be able to access a single value lets say the first item with the key "0" -> bookieName, how would i do that using loginDetails
Firs booked is a Bool and no need for private enum Codingkeys if you won't rename the keys
struct Booking: Codable {
let bookieName : String
let bookieNumber: String
let booked: Bool
let bookingTime: String
}
Second decode like this
let loginDetails = try decoder.decode([String:Booking].self, from: response.data!)
The root object is a dictionary with String keys and Bookings values – please name structs with a starting capital letter.
So you have to decode
let loginDetails = try decoder.decode([String:Bookings].self, from: response.data!)

Parsing Twitter API Search Response in Swift with TwitterKit

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

Array of dictionaries to JSON in Swift

I'm trying to send an array of dictionaries as one of the parameters to an Alamofire request. However, Alamofire is failing on the request.
class PromoCategory {
var promoCategoryId : Int?
var activityId : Int?
var promoCategoryName : String?
var activityName : String!
var statusCd : Int?
init() {
promoCategoryId = 0
promoCategoryName = ""
}
func getDictFormat() -> [String: Any] {
if activityId == nil { activityId = 0 }
if statusCd == nil { statusCd = 0 }
return [
"promoCategoryId" : "\(promoCategoryId!)",
"activityId" : "\(activityId!)",
"promoCategoryName" : promoCategoryName!,
"activityName" : activityName!,
"statusCd" : "\(statusCd!)"
]
}
}
var promoCat = [[String: Any]]()
for cat in promoCategories {
let element = cat.getDictFormat()
promoCat.append(element)
}
var params : [String : Any] = [:]
params["person_id"] = kPersonId
params["person_promo_id"] = promo.personPromoId
params["promo_page_id"] = promo.promoPageId
params["seq_no"] = promo.seqNo
params["promo_type"] = promoTypeString
params["page_name"] = promo.pageName
params["image_name"] = promo.imageName
params["start_date"] = promo.startDate
params["end_date"] = promo.endDate
params["website"] = promo.website
...
params["promoCategories"] = promoCat
Alamofire.request(promoUrl!, method: .post, parameters: params, encoding: JSONEncoding.default, headers: nil)
.validate()
.responseJSON { response in
switch response.result {
case .success(let data):
self.json = JSON(data)
print(self.json as Any)
DispatchQueue.main.async(execute: { () -> Void in
self.dismiss(animated: true, completion: nil)
HUD.hide()
})
case .failure(let error):
self.logApiError(url: (...)
}
}
The error:
Request failed with error:
responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error
Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character
0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
If I remove the promoCategories parameter, then it works fine. The params object ends up looking like this:
{
address = "";
bgColorBlue = "0.28936631944444";
bgColorGreen = "0.3072916666666701";
bgColorRed = "0.3063227289789799";
city = "";
"contact_name" = "John Smith";
"contact_phone" = 3065554611;
"country_cd" = CA;
"end_date" = "2017-01-26 21:06:08Z";
"facility_name" = "Conexus Arts Centre";
"image_name" = "EV1.20170126210608302479028.jpg";
latitude = 0;
longitude = 0;
"page_name" = "Test Promo";
"person_id" = 1;
"person_promo_id" = 21;
promoCategories = (
{
activityId = 68;
activityName = "Fashion & Beauty";
promoCategoryId = 271;
promoCategoryName = Accessories;
statusCd = 0;
},
{
activityId = 68;
activityName = "Fashion & Beauty";
promoCategoryId = 273;
promoCategoryName = Beauty;
statusCd = 0;
},
{
activityId = 68;
activityName = "Fashion & Beauty";
promoCategoryId = 270;
promoCategoryName = Fashion;
statusCd = 0;
}
);
"promo_page_id" = 0;
"promo_type" = event;
"prov_state_cd" = "";
"seq_no" = 0;
"start_date" = "2017-01-26 21:06:08Z";
website = "";
}
Is this the approach I should be using? Is there something I have missed? Thanks.

Embedded json data in swift three levels

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)
}
}
}