Unable to parse the json in swift - json

I have a json response as follows
{
"payment_methods" = (
{
code = checkmo;
title = "Check / Money order";
},
{
code = "paypal_express";
title = "PayPal Express Checkout";
},
{
code = banktransfer;
title = "Bank Transfer Payment";
}
);
totals = {
"base_currency_code" = USD;
"base_discount_amount" = "-258.38";
"base_grand_total" = "2725.37";
"base_shipping_amount" = 400;
"base_shipping_discount_amount" = 0;
"base_shipping_incl_tax" = 400;
"base_shipping_tax_amount" = 0;
"base_subtotal" = "2583.75";
"base_subtotal_with_discount" = "2325.37";
"base_tax_amount" = 0;
"coupon_code" = ADAMAS10;
"discount_amount" = "-258.38";
"grand_total" = "2725.37";
items = (
{
"base_discount_amount" = "134.2";
"base_price" = 1342;
"base_price_incl_tax" = 1342;
"base_row_total" = 1342;
"base_row_total_incl_tax" = 1342;
"base_tax_amount" = 0;
"discount_amount" = "134.2";
"discount_percent" = 10;
"item_id" = 3292;
name = BWBCA14KWGVC015;
options = "[{\"value\":\"18K White Gold\",\"label\":\"Metal\"},{\"value\":\"2\",\"label\":\"size\"}]";
price = 1342;
"price_incl_tax" = 1342;
qty = 1;
"row_total" = 1342;
"row_total_incl_tax" = 1342;
"row_total_with_discount" = 0;
"tax_amount" = 0;
"tax_percent" = 0;
"weee_tax_applied" = "[]";
"weee_tax_applied_amount" = 0;
},
{
"base_discount_amount" = "124.18";
"base_price" = "1241.75";
"base_price_incl_tax" = "1241.75";
"base_row_total" = "1241.75";
"base_row_total_incl_tax" = "1241.75";
"base_tax_amount" = 0;
"discount_amount" = "124.18";
"discount_percent" = 10;
"item_id" = 3342;
name = BWBCA14KWGCV008;
options = "[{\"value\":\"18K White Gold\",\"label\":\"Metal Type\"},{\"value\":\"1.75\",\"label\":\"Ring Size\"}]";
price = "1241.75";
"price_incl_tax" = "1241.75";
qty = 1;
"row_total" = "1241.75";
"row_total_incl_tax" = "1241.75";
"row_total_with_discount" = 0;
"tax_amount" = 0;
"tax_percent" = 0;
"weee_tax_applied" = "[]";
"weee_tax_applied_amount" = 0;
}
);
"items_qty" = 2;
"quote_currency_code" = USD;
"shipping_amount" = 400;
"shipping_discount_amount" = 0;
"shipping_incl_tax" = 400;
"shipping_tax_amount" = 0;
subtotal = "2583.75";
"subtotal_incl_tax" = "2583.75";
"subtotal_with_discount" = "2325.37";
"tax_amount" = 0;
"total_segments" = (
{
code = subtotal;
title = Subtotal;
value = "2583.75";
},
{
code = discount;
title = "Discount (ADAMAS10)";
value = "-258.38";
},
{
code = shipping;
title = "Shipping & Handling (Flat Shipping Charge - Flat Shipping Charge)";
value = 400;
},
{
area = taxes;
code = tax;
"extension_attributes" = {
"tax_grandtotal_details" = (
);
};
title = Tax;
value = 0;
},
{
area = footer;
code = "grand_total";
title = "Grand Total";
value = "2725.37";
}
);
"weee_tax_applied_amount" = "<null>";
};
}
I need to fetch values from total segments.The code is shipping and value is Shipping & Handling (Flat Shipping Charge - Flat Shipping Charge.
I tried to parse the json using the below code
if let res = json as? [String:Any]
{
if let dict = res as? [String:Any]
{
if let total = dict as? [[String:Any]]
{
}
}
}
I am getting value till dict.But i am getting nil in the total variable.
How to get the total segments value?

you're missing out to mention the inner key path of the dictionary. hope this is what you're trying to do
if let res = json as? [String:Any] {
if let paymentMethods = res["payment_methods"] as? [[String:Any]] {
}
if let totals = res["totals"] as? [String:Any] {
if let items = totals["items"] as? [[String:Any]] {
}
}
}

Use this to get the total_segments and value of all code keys:
var codes = [String]()
if let res = json as? [String:Any] {
if let totals = res["totals"] as? [String:Any] {
if let totalSegments = totals["total_segments"] as? [[String:Any]] {
for segment in totalSegments {
if let code = segment["code"] as? String {
codes.append(code)
}
}
}
}
}

Related

Using custom date format

I have this working script to sent mails with data from a Google sheet:
function SendEmail() {
let timestamp = 0
let poid = 1
let sku = 2
let qty = 3
let description = 4
let licenseid = 5
let itcost = 6
let total = 7
let company = 8
let contact = 9
let contactmail = 10
let endusermail = 11
let address = 12
let country = 13
let status = 14
let suppliermail = 15
let currency = 16
let otherinfo = 17
let brand = 18
let comment = 19
let cc = 20
let emailTemp = HtmlService.createTemplateFromFile("MAIL")
let ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DATA")
let sd = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DATA2")
let data = ws.getRange("A2:V" + ws.getLastRow()).getValues()
let sData = sd.getRange("B2:J" + sd.getLastRow()).getValues()
let sInfo = sData.map(function (r) { return r[0] })
data = data.filter(function (r) { return r[14] == 'SENTNOW' })
if (data.length) {
let found = false
data.forEach(function (row) {
emailTemp.ts = row[timestamp].toLocaleString("da-DK")
emailTemp.po = row[poid]
emailTemp.co = row[contact]
emailTemp.cm = row[company]
emailTemp.ad = row[address]
emailTemp.cu = row[country]
emailTemp.cn = row[contactmail]
emailTemp.sk = row[sku]
emailTemp.de = row[description]
emailTemp.qt = row[qty]
emailTemp.it = (row[itcost]).toLocaleString("da-DK")
emailTemp.to = (row[total]).toLocaleString("da-DK")
emailTemp.ce = row[comment]
emailTemp.cy = row[currency]
emailTemp.eu = row[endusermail]
emailTemp.li = row[licenseid]
emailTemp.ot = row[otherinfo]
let indexSupp = sInfo.indexOf(row[15])
if (indexSupp > -1) {
//only change status if supplierdata email is found
found = true
emailTemp.spname = sData[indexSupp][1]
emailTemp.saddress1 = sData[indexSupp][2]
emailTemp.saddress2 = sData[indexSupp][3]
emailTemp.scountry = sData[indexSupp][4]
emailTemp.sterms = sData[indexSupp][5]
emailTemp.scurrency = sData[indexSupp][6]
emailTemp.sothers = sData[indexSupp][7]
emailTemp.vat = sData[indexSupp][8] * 100
emailTemp.totvat = (row[total] * sData[indexSupp][8]).toLocaleString("da-DK")
emailTemp.totandvat = (row[total] + (row[total] * sData[indexSupp][8])).toLocaleString("da-DK")
let subjectLine = "Subject line # " + row[poid]
let htmlMessage = emailTemp.evaluate().getContent()
//only send email if supplierdata email is found
try {
GmailApp.sendEmail(
row[suppliermail],
subjectLine,
"",
{ name: 'Name', htmlBody: htmlMessage, bcc: 'myemail#domain.com' })
}
catch (err) {
SpreadsheetApp.getUi().alert(err)
}
}
})
if (found) {
let sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("DATA")
.getRange('O2:O')
.createTextFinder('SENTNOW')
.replaceAllWith('SENT')
}
}
}
Only problem is the date format emailTemp.ts = row[timestamp].toLocaleString("da-DK")
This give output date-format "11.2.2022 06.00.00" within the e-mail sent to the reciever.
What I wish is the date to be just "02/11/2022"
I tried emailTemp.ts = row[timestamp].toLocaleString("da-DK").getDisplayValue() but that was not working.
Any suggestions ?
You're going to have to figure out your time zone but try this.
emailTemp.ts = Utilities.formatDate(row[timestamp],"GMT","dd/MM/yyyy");
Reference
Utilities.formatDate()

how to parse multiple JSON structures in spark program

I am working on parsing logs(Json format) in Scala. I don't know how to proceed. I may get different kinds of logs to be processed.
how do i write/design my code to handle different types of Json structures?
can i give my Scala program a schema and let it parse?
I wrote some code using Object mapper and read through the nodes but i want a more structure agnostic approach.
I am not sure where to start. please point me to some reading or examples. i tried to google or search in Stackoverflow resulting in too many examples and it is confusing as i am learning Scala also.
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.Path
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import org.apache.spark.sql.hive.HiveContext
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import org.apache.spark.rdd.RDD;
sc.setLogLevel("OFF");
val args = sc.getConf.get("spark.driver.args").split("\\s+")
args.foreach(println);
var envStr = "dev";
var srcStr = "appm"
val RootFolderStr = "/source_folder/";
val DestFolderStr = "/dest_folder/";
val dateformatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'");
val formatter = new SimpleDateFormat("yyyy-MM-dd");
val theMonthFormatter = new SimpleDateFormat("yyyy-MM");
var fromDay: Date = formatter.parse("2018-04-29");
var toDay: Date = formatter.parse("2018-05-01");
if (args.length < 2) {
printf("usage: need at least 2 parameters in spark.driver.args");
sys.exit(2);
}
envStr = args(0).toLowerCase();
srcStr = args(1).toLowerCase();
if (args.length == 4) {
fromDay = formatter.parse(args(2));
toDay = formatter.parse(args(3));
}
if (args.length == 2) {
// default to be yesterday to today
toDay = formatter.parse(formatter.format(Calendar.getInstance().getTime()));
val previousDay = Calendar.getInstance();
previousDay.add(Calendar.DATE, -1);
fromDay = formatter.parse(formatter.format(previousDay.getTime()));
}
// get the sub-folder for the monthly partition
val monthFolder = theMonthFormatter.format(fromDay);
var rootFolder = RootFolderStr.replaceAll("ENV", envStr) + monthFolder;
rootFolder = rootFolder.replaceAll("SRC", srcStr);
val destFolder = DestFolderStr.replaceAll("ENV", envStr);
var toCalendar = Calendar.getInstance();
toCalendar.setTime(toDay);
toCalendar.add(Calendar.DATE, 1);
// need to consider the case across the month boundary
val toDay2 = formatter.parse(formatter.format(toCalendar.getTime()));
// filter out .tmp files and 0-size files
// .tmp files are not safe to read from, it's possible that the files are under updating by Flume job and the message data is incomplete
// when the Spark job starts to read from it.
val pathInfos = FileSystem.get(sc.hadoopConfiguration).listStatus(new Path(rootFolder));
// filter out the 0-length files, .tmp files which is of today
val allfiles = pathInfos.filter(fileStatus => {
if (fileStatus.getLen == 0)
false
else {
val aPath = fileStatus.getPath().getName();
// use the modification time is more accurate.
val lastTime = fileStatus.getModificationTime();
val aDate = new Date(lastTime);
// all files between fromDay and toDay2
aDate.after(fromDay) && aDate.before(toDay2);
}
}
).map(_.getPath.toString);
case class event_log(
time_stp: Long,
msg_sze: Int,
msg_src: String,
action_path: String,
s_code: Int,
s_desc: String,
p_code: String,
c_id: String,
m_id: String,
c_ip: String,
c_gp: String,
gip: String,
ggip: String,
rbody: String
);
def readEvents(fileList: Array[String], msgSrc: String, fromTS: Long, toTS: Long): RDD[(event_log)] = {
val records =
sc.sequenceFile[Long, String](fileList.mkString(","))
.filter((message) => {
(message._1 >= fromTS && message._1 < toTS);
}
)
val eventLogs = records.map((message) => {
val time_stp = message._1;
var msg_sze = message._2.length();
var c_id = ""
var m_id = "";
var p_code = "";
var c_ip = "";
var c_gp = "";
var gip = "";
var ggip = "";
var rbody = "";
var action_path = "";
var s_code: Int = 200;
var s_desc = "";
try {
// parse the message
val mapper = new ObjectMapper();
val aBuff = message._2.getBytes();
val root = mapper.readTree(aBuff);
var aNode = root.path("rbody");
rbody = aNode.textValue();
if (rbody != null && rbody.length() > 0) {
val mapper_2 = new ObjectMapper();
val aBuff_2 = rbody.getBytes();
var root2 = mapper_2.readTree(aBuff_2);
aNode = root2.path("p_code");
if (aNode != null && aNode.isValueNode())
p_code = String.valueOf(aNode.intValue());
aNode = root2.path("mkay");
if (aNode != null && aNode.isObject()) {
root2 = aNode;
}
{
aNode = root2.get("c_id");
if (aNode != null && aNode.isValueNode())
c_id = aNode.textValue();
aNode = root2.get("m_id");
if (aNode != null && aNode.isValueNode()) {
m_id = String.valueOf(aNode.intValue());
}
}
}
aNode = root.path("c_ip");
c_ip = aNode.textValue();
aNode = root.path("c_gp");
c_gp = aNode.textValue();
aNode = root.path("gip");
gip = aNode.textValue();
aNode = root.path("ggip");
ggip = aNode.textValue();
aNode = root.path("action_path");
action_path = aNode.textValue();
aNode = root.path("s_code");
val statusNodeValue = aNode.textValue().trim();
s_code = Integer.valueOf(statusNodeValue.substring(0, 3));
s_desc = statusNodeValue.substring(3).trim();
}
catch {
// return empty string as indicator that it's not a well-formatted JSON message
case jex: JsonParseException => {
msg_sze = 0
};
case ioEx: java.io.IOException => {
msg_sze = 0
};
case rtEx: JsonMappingException => {
msg_sze = 0
};
}
event_log(time_stp, msg_sze, msgSrc, action_path, s_code, s_desc,
p_code, c_id, m_id,
c_ip, c_gp, gip, ggip,
rbody);
});
eventLogs;
}
val hiveContext = new HiveContext(sc)
if (allfiles.length == 0)
sys.exit(3);
val fromTime = fromDay.getTime();
val toTime = toDay.getTime();
val events = readEvents(allfiles, srcStr, fromTime, toTime);
val df = hiveContext.createDataFrame(events).coalesce(1);
df.write.parquet(destFolder);
sys.exit(0);

parsing the nested json in swift

I am new to swift. Here is a deserialized JSON
Optional({
data = (
{
comments = (
{
comments = good;
"created_date" = "2018-01-01";
id = 2;
likes = 0;
"news_id" = 4;
status = 1;
"user_id" = 5;
}
);
date = 1510167600000;
id = 4;
images = "0c980d3f9cd0393a46bb04995d16177a.jpg";
likes = 25;
title = facebook;
totalcoments = 1;
},
{
comments = (
{
comments = "Good News";
"created_date" = "2018-01-01";
id = 1;
likes = 2;
"news_id" = 7;
status = 1;
"user_id" = 5;
},
{
comments = "well good";
"created_date" = "2018-01-02";
id = 3;
likes = 0;
"news_id" = 7;
status = 1;
"user_id" = 5;
},
{
comments = "well good";
"created_date" = "2018-01-02";
id = 4;
likes = 0;
"news_id" = 7;
status = 1;
"user_id" = 5;
},
{
comments = "well good";
"created_date" = "2018-01-03";
id = 5;
likes = 0;
"news_id" = 7;
status = 1;
"user_id" = 5;
}
);
date = 1511377200000;
id = 7;
images = "0c980d3f9cd0393a46bb04995d16177a.jpg";
likes = 3;
title = don;
totalcoments = 4;
},
{
comments = (
);
date = 1510513200000;
id = 8;
images = "0c980d3f9cd0393a46bb04995d16177a.jpg";
likes = 90;
title = Dell;
totalcoments = 0;
},
{
comments = (
);
date = 1515351600000;
id = 14;
images = "0c980d3f9cd0393a46bb04995d16177a.jpg";
likes = 0;
title = dfsfdsfdfs;
totalcoments = 0;
}
);
message = "Success.";
newsurl = "http://dev.nsol.sg/projects/sneakers/assets/brand_images/thumb/";
success = 1;
totalnews = 4;
})
Here in following class i am trying to parse the json
import UIKit
class getData: NSObject {
var descriptionn : String = ""
var image : String = ""
var likes : String = ""
var comments : Int = 0
var com:String=""
var like:String = ""
func getDataForTableView(results: [[String:Any]], index : Int){
var productArray = [String:Any]()
productArray = results[index]
descriptionn = productArray["title"]! as! String
image = productArray["images"]! as! String
likes=productArray["likes"]! as! String
comments=productArray["totalcoments"]! as! Int
/*{
comments = (
{
comments = good;
"created_date" = "2018-01-01";
id = 2;
likes = 0;
"news_id" = 4;
status = 1;
"user_id" = 5;
}
);*/
//code for parsing the "comments" section of json is
let comment=productArray["comments"] as! [String:Any]?
com = comment!["comments"] as! String
like = comment!["likes"] as! String
}
}
The code for populating the table view cell is below
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "discoveryNewscell") as! DiscoveryNewsTableViewCell
classObject.getDataForTableView(results: results, index: indexPath.row)
cell.sneakerImageView.image=filteredsneakernews[indexPath.row].image
cell.newsTitle.text = classObject.descriptionn
cell.likes.text=classObject.likes
cell.comments.text=String(classObject.comments)
let imageURLPathString = newsurl + classObject.image
print("comments")
print(classObject.image)
let url1 = URL(string: imageURLPathString)
print("xyz", url1)
let data = try? Data(contentsOf: url1!)
if let imageData = data {
let image = UIImage(data: imageData)
cell.sneakerImageView.image = image
}
return cell
}
Here is didSelectRowAt Index path function
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storybaord=UIStoryboard(name: "Main", bundle: nil)
let tabBar=storybaord.instantiateViewController(withIdentifier: "tabBar") as! UITabBarController
let DVC = tabBar.viewControllers?[0] as! NewsViewController
classObject.getDataForTableView(results: results, index: indexPath.row)
let imageURLPathString = newsurl + classObject.image
let url1 = URL(string: imageURLPathString)
print("xyz", url1)
let data = try? Data(contentsOf: url1!)
if let imageData = data {
let image = UIImage(data: imageData)
DVC.getImage = image!
}
let news = classObject.descriptionn
DVC.getNews = news
DVC.getnumberOfComment=classObject.comments
print("comment")
//code for passing "comment" part of json to view controller
print(classObject.like)
print(classObject.com)
DVC.getlikes=classObject.like
DVC.getcomment=classObject.com
self.navigationController?.pushViewController(tabBar, animated: true)
}
I want when a particular row is selected from table view it should display the number of "likes" and "comments" that are from nested part of JSON on "Likes Screen" view controller
comments = (
{
comments = good;
"created_date" = "2018-01-01";
id = 2;
likes = 0;
"news_id" = 4;
status = 1;
"user_id" = 5;
}
);
How to read and parse that nested "Comments" in JSON? You can download the project from this link .https://drive.google.com/file/d/1VYM4nywaBYDP2BcyBYPPNUYAu_18mhd9/view?usp=sharing

Swift Firebase data format

when I did asked firebase the following.
print("\(WarSerArray[CompanyData.companyName]!.allValues)")
print("keys\(WarSerArray[CompanyData.companyName]!.allKeys)")
it printed out this information.
[{
PhonNumber = 7607588500;
address = "2378 Primrose Ave. Vista, CA. 92083";
currentStoreArray = Headquarters;
email = "james#opportunitysoftware.com";
faxNumber = "";
key = "-KLSM8y0BDfs6B1jtsA5";
name = "Service Center 1";
}]
keys[-KLSM8y0BDfs6B1jtsA5]
[{
PhonNumber = 7607588500;
address = "2378 Primrose Ave. Vista, CA. 92083";
currentStoreArray = Headquarters;
email = "james#opportunitysoftware.com";
faxNumber = "";
key = "-KLSM8zu6AFKa7V0beCh";
name = "Warehouse 1";
}]
keys[-KLSM8zu6AFKa7V0beCh]
how do I get name?
var CompanyData = CompanyDataStruct()
struct CompanyDataStruct {
var key = ""
var webpage:String! = ""
var OwnerName:String! = ""
var address:String! = ""
var managerPNumber:String = ""
var dueOnOrder = 0.0
var email:String! = ""
var fax:String! = ""
var itemsOrderHistory:String! = ""
var companyName:String! = ""
var money = 0.0
var notes:String! = ""
var tax = 0.0
var pNumber:String = ""
var ManagerContact = ""
var opw:String! = ""
var mpw:String! = ""
var OwedToCompany = 0.0
var OwedString:String! = ""
var taxID:String! = ""
var reSalesID:String! = ""
var BoxCount = 0
var secondTicketID:String! = ""
var secondTicketNumber = 0
var useSecondTicketID = false
var printerSettings = ""
var quoteDays = 0
var fulfillmentPrinter = false
var fulfillmentEmail = false
var printBill = false
var emailBill = false
var system = false
var printReceipt = false
var emailReceipt = false
var theFulFillEmail = ""
var logoName = ""
var delivery = false
var ac1 = ""
var ac2 = ""
var ac3 = ""
var storeID = ""
var warehouse = ""
var serviceCenter = ""
var currentStore = ""
var StoreCount = 0
var WareHouseCount = 0
var ServiceCenterCount = 0
var MoneySymbol = ""
var refundLevel = 0
var shareBarcode = true
var LoGoImage = DefaultImage
}
var WarehouseData2 = WareServiceStruct()
struct WareServiceStruct {
var name = String()
var address = String()
var currentStoreArray = String()
var phoneNumber = String()
var faxNumber = String()
var email = String()
var key = String()
}
let WareSerRef = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ")
let WareSerRefName = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ").child("name")
let WareSerRefAddress = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ").child("address")
let WarSerRefCurrentStore = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ").child("CurrentStore")
let WareSerRefPhone = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ").child("PhoneNumber")
let WareSerRefFax = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ").child("faxNumber")
let WareSerRefEmail = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ").child("email")
let WareSerRefKey = FIRDatabase.database().reference().child("Owner").child("CompanyName").child("WareServ").child("key")
func WarehouseFirebaseSetter(sedner: WareServiceStruct) {
let key = WareSerRef.childByAutoId().key
WarehouseData2 = sedner
WarehouseData2.key = key
let WareToAdd = FBWarhouseData
let childUpdates = ["/Warehouse /\(CompanyData.companyName)/\(key)":WareToAdd]
WareSerRef.updateChildValues(childUpdates)
}
var FBWarhouseData = ["address" : WarehouseData2.address,"currentStoreArray" : WarehouseData2.currentStoreArray,"email" : WarehouseData2.email,"faxNumber" : WarehouseData2.faxNumber,"PhonNumber" : WarehouseData2.phoneNumber,"name" : WarehouseData2.name,"key" : WarehouseData2.key] as NSDictionary

Trouble with nested Json data

I'm having a ton of trouble trying to access the nested json data (pasted at the bottom). I'm able write:
var dataResults = jsonResult["data"] as NSDictionary
In order to create a dictionary containing the data within "data", however, Xcode will not allow me to call on anything within "data" such as the information within "current_condition". I've tried to make current_condition it's own dictionary like so:
var results = dataResults["current_condition"] as NSDictionary
But it would seem that this is turning up as nil
I have also attempted accessing using the standard method for calling nested loops:
var dataResults = jsonResult["data"]["current_condition"] as NSDictionary
But this results in a compiler error.
Any help? Much appreciated!
Json data:
{
data = {
"current_condition" = (
{
cloudcover = 0;
humidity = 68;
"observation_time" = "01:39 AM";
precipMM = "0.0";
pressure = 1017;
"temp_C" = 20;
"temp_F" = 68;
visibility = 10;
weatherCode = 143;
weatherDesc = (
{
value = Mist;
}
);
weatherIconUrl = (
{
value = "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0006_mist.png";
}
);
winddir16Point = NE;
winddirDegree = 50;
windspeedKmph = 7;
windspeedMiles = 4;
}
);
request = (
{
query = "London, United Kingdom";
type = City;
}
);
weather = (
{
date = "2014-07-25";
precipMM = "1.5";
tempMaxC = 27;
tempMaxF = 81;
tempMinC = 14;
tempMinF = 57;
weatherCode = 353;
weatherDesc = (
{
value = "Light rain shower";
}
);
weatherIconUrl = (
{
value = "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0009_light_rain_showers.png";
}
);
winddir16Point = NE;
winddirDegree = 54;
winddirection = NE;
windspeedKmph = 15;
windspeedMiles = 10;
},
{
date = "2014-07-26";
precipMM = "5.8";
tempMaxC = 28;
tempMaxF = 83;
tempMinC = 16;
tempMinF = 61;
weatherCode = 176;
weatherDesc = (
{
value = "Patchy rain nearby";
}
);
weatherIconUrl = (
{
value = "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0009_light_rain_showers.png";
}
);
winddir16Point = NNE;
winddirDegree = 12;
winddirection = NNE;
windspeedKmph = 11;
windspeedMiles = 7;
},
{
date = "2014-07-27";
precipMM = "0.2";
tempMaxC = 26;
tempMaxF = 80;
tempMinC = 13;
tempMinF = 55;
weatherCode = 116;
weatherDesc = (
{
value = "Partly Cloudy";
}
);
weatherIconUrl = (
{
value = "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png";
}
);
winddir16Point = NW;
winddirDegree = 321;
winddirection = NW;
windspeedKmph = 14;
windspeedMiles = 9;
},
{
date = "2014-07-28";
precipMM = "1.9";
tempMaxC = 26;
tempMaxF = 78;
tempMinC = 12;
tempMinF = 54;
weatherCode = 116;
weatherDesc = (
{
value = "Partly Cloudy";
}
);
weatherIconUrl = (
{
value = "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png";
}
);
winddir16Point = N;
winddirDegree = 351;
winddirection = N;
windspeedKmph = 13;
windspeedMiles = 8;
},
{
date = "2014-07-29";
precipMM = "0.0";
tempMaxC = 28;
tempMaxF = 82;
tempMinC = 16;
tempMinF = 60;
weatherCode = 113;
weatherDesc = (
{
value = Sunny;
}
);
weatherIconUrl = (
{
value = "http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0001_sunny.png";
}
);
winddir16Point = NNW;
winddirDegree = 329;
winddirection = NNW;
windspeedKmph = 13;
windspeedMiles = 8;
}
);
};
}
Oddly enough, I have a sample weather app that I converted to Swift. I get my data elsewhere, but I found this library to be a great way to deal with JSON in Swift: https://github.com/dankogai/swift-json/. Much cleaner and easier.
It's because the subscript in Dictionary returns an optional:
subscript (key: KeyType) -> ValueType?
Meaning you have to unwrap the optional before you can downcast:
let dataResults = jsonResult["data"]! as NSDictionary
let results = dataResults["current_condition"]! as NSDictionary
As of Beta 3 you can access the value directly without downcasting, like this:
let dataResults = jsonResult["data"]!
let results = dataResults["current_condition"]
However I would suggest you wrap it around an if-let to make sure you don't unwrap nil values.