Reputation: 77
I want to download, parse and save data from a json file using core data. Generally my code works but when the content of the json isn't as expected I run in to problems. Maybe someone can give some advice for a better approach. Here is my code:
//MARK: - REST calls
// This makes the GET call to ATI. It simply gets the some test data
and displays it on the screen.
func getATITodayHoursDataEntertain() {
print("getATITodayHoursDataEntertain")
// set up the base64-encoded credentials
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
config.HTTPAdditionalHeaders = ["Authorization" : authString]
let session = NSURLSession(configuration: config)
let url = NSURL(string: "https://apirest.atinternet-solutions.com/data/v2/json/getData?code=1KVVaC&max-results=30&page-num=1")
session.dataTaskWithURL(url!, completionHandler: { ( data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
guard let realResponse = response as? NSHTTPURLResponse where
realResponse.statusCode == 200 else {
print("Not a 200 response - getATITodayHoursDataEntertain")
print(response)
return
}
do {
if let jsonString = NSString(data:data!, encoding: NSUTF8StringEncoding) {
let _ = jsonString
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
let jsonContext = ((jsonDictionary["DataFeed"] as! NSArray) [0] as! NSDictionary) ["Context"] as! NSDictionary
let period = (((jsonContext) ["Periods"] as! NSArray) [0] as! NSDictionary) ["Value"] as! String
let jsonContent = ((
["DataFeed"] as! NSArray) [0] as! NSDictionary) ["Rows"] as! NSArray
let currentDayTime = jsonContent.count
var hour0 = 0
var hour1 = 0
var hour2 = 0
var hour3 = 0
var hour4 = 0
var hour5 = 0
var hour6 = 0
var hour7 = 0
var hour8 = 0
var hour9 = 0
var hour10 = 0
var hour11 = 0
var hour12 = 0
var hour13 = 0
var hour14 = 0
var hour15 = 0
var hour16 = 0
var hour17 = 0
var hour18 = 0
var hour19 = 0
var hour20 = 0
var hour21 = 0
var hour22 = 0
var hour23 = 0
if (currentDayTime >= 1) {
hour0 = (jsonContent[0] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 2) {
hour1 = (jsonContent[1] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 3) {
hour2 = (jsonContent[2] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 4) {
hour3 = (jsonContent[3] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 5) {
hour4 = (jsonContent[4] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 6) {
hour5 = (jsonContent[5] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 7) {
hour6 = (jsonContent[6] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 8) {
hour7 = (jsonContent[7] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 9) {
hour8 = (jsonContent[8] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 10) {
hour9 = (jsonContent[9] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 11) {
hour10 = (jsonContent[10] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 12) {
hour11 = (jsonContent[11] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 13) {
hour12 = (jsonContent[12] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 14) {
hour13 = (jsonContent[13] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 15) {
hour14 = (jsonContent[14] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 16) {
hour15 = (jsonContent[15] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 17) {
hour16 = (jsonContent[16] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 18) {
hour17 = (jsonContent[17] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 19) {
hour18 = (jsonContent[18] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 20) {
hour19 = (jsonContent[19] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 21) {
hour20 = (jsonContent[20] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 22) {
hour21 = (jsonContent[21] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 23) {
hour22 = (jsonContent[22] as! NSDictionary) ["m_page_loads"] as! Int
}
if (currentDayTime >= 24) {
hour23 = (jsonContent[23] as! NSDictionary) ["m_page_loads"] as! Int
}
let jsonTotals = ((jsonDictionary["DataFeed"] as! NSArray) [0] as! NSDictionary) ["Totals"] as! NSArray
let all = jsonTotals[0] ["m_page_loads"] as! Int
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("TodayHoursDataEntertain", inManagedObjectContext:managedContext)
let todayHour = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
todayHour.setValue(period, forKey: "period")
todayHour.setValue(hour0, forKey: "hour0")
todayHour.setValue(hour1, forKey: "hour1")
todayHour.setValue(hour2, forKey: "hour2")
todayHour.setValue(hour3, forKey: "hour3")
todayHour.setValue(hour4, forKey: "hour4")
todayHour.setValue(hour5, forKey: "hour5")
todayHour.setValue(hour6, forKey: "hour6")
todayHour.setValue(hour7, forKey: "hour7")
todayHour.setValue(hour8, forKey: "hour8")
todayHour.setValue(hour9, forKey: "hour9")
todayHour.setValue(hour10, forKey: "hour10")
todayHour.setValue(hour11, forKey: "hour11")
todayHour.setValue(hour12, forKey: "hour12")
todayHour.setValue(hour13, forKey: "hour13")
todayHour.setValue(hour14, forKey: "hour14")
todayHour.setValue(hour15, forKey: "hour15")
todayHour.setValue(hour16, forKey: "hour16")
todayHour.setValue(hour17, forKey: "hour17")
todayHour.setValue(hour18, forKey: "hour18")
todayHour.setValue(hour19, forKey: "hour19")
todayHour.setValue(hour20, forKey: "hour20")
todayHour.setValue(hour21, forKey: "hour21")
todayHour.setValue(hour22, forKey: "hour22")
todayHour.setValue(hour23, forKey: "hour23")
todayHour.setValue(all, forKey: "all")
do {
try managedContext.save()
TodayHoursData.append(todayHour)
print("getATITodayHoursDataEntertain data saved")
} catch let error as NSError {
print("getATITodayHoursDataEntertain - Could not save \(error), \(error.userInfo)")
}
}
} catch {
print("bad things happened - getATITodayHoursDataEntertain")
}
}).resume()
}
Here is an example of the json:
{
DataFeed: [
{
Context: {
Spaces: [
{
Sites: [
{
Id: "560038",
Label: "Entertain VoD TopLists",
Currency: "USD",
TimeZone: "(UTC+01:00) W. Europe Standard Time",
Start: "2015-04-27",
L2s: null
}
]
}
],
Periods: [
{
Value: "2016-05-01T00:00:00,2016-05-01T20:46:59"
}
],
Ranges: [
{
Id: "page-num",
Value: "1"
},
{
Id: "max-results",
Value: "30"
},
{
Id: "url-next",
Value: "https://apirest.atinternet-solutions.com/v2/getdata?page-num=2&filter=%7bd_page_chap1%3a%7b%24eq%3a%27Buy%27%7d%7d&sort=%7bd_time_hour_event%7d&columns=%7bd_time_hour_event%2cm_page_loads%7d&include=%7btotal%3aall%2ccontext%7d&period=%7bR%3a%7bD%3a%270%27%7d%7d&space=%7bs%3a560038%7d&max-results=30"
}
],
Profile: {
Language: "EN",
FirstDayWeek: "Mo"
}
},
Columns: [
{
Name: "d_time_hour_event",
Label: "Hour (event)",
Category: "Dimension",
Type: "Integer",
CustomerType: "Hour"
},
{
Name: "m_page_loads",
Label: "Loads",
Category: "Metric",
Type: "Integer",
CustomerType: "Integer",
Summable: true,
Pie: true
}
],
Rows: [
{
d_time_hour_event: 0,
m_page_loads: 534
},
{
d_time_hour_event: 1,
m_page_loads: 315
},
{
d_time_hour_event: 2,
m_page_loads: 148
},
{
d_time_hour_event: 3,
m_page_loads: 91
},
{
d_time_hour_event: 4,
m_page_loads: 74
},
{
d_time_hour_event: 5,
m_page_loads: 74
},
{
d_time_hour_event: 6,
m_page_loads: 87
},
{
d_time_hour_event: 7,
m_page_loads: 156
},
{
d_time_hour_event: 8,
m_page_loads: 218
},
{
d_time_hour_event: 9,
m_page_loads: 344
},
{
d_time_hour_event: 10,
m_page_loads: 438
},
{
d_time_hour_event: 11,
m_page_loads: 435
},
{
d_time_hour_event: 12,
m_page_loads: 541
},
{
d_time_hour_event: 13,
m_page_loads: 739
},
{
d_time_hour_event: 14,
m_page_loads: 758
},
{
d_time_hour_event: 15,
m_page_loads: 883
},
{
d_time_hour_event: 16,
m_page_loads: 888
},
{
d_time_hour_event: 17,
m_page_loads: 821
},
{
d_time_hour_event: 18,
m_page_loads: 950
},
{
d_time_hour_event: 19,
m_page_loads: 1218
},
{
d_time_hour_event: 20,
m_page_loads: 2000
}
],
Totals: [
{
type: "all",
m_page_loads: 11712
}
]
}
]
}
My problem is that very rarely it can happen that there is no result for one or more hours of the day. In this cases my basic approach of counting the numbers of items in the json fails. Can anyone give me a suggestion for a better approach to avoid this problem?
I'm currently using Xcode 7.2 and wrote my code in swift2.
Please don't be to harsh. As you can guess I am not really a developer and also completely new to swift.
br
nikolay
Upvotes: 3
Views: 459
Reputation: 1000
Instead of writing your hour comparisons like this:
if (currentDayTime >= 1) {
hour0 = (jsonContent[0] as! NSDictionary) ["m_page_loads"] as! Int
}
A safer way to write them would be something like this:
if currentDayTime >= 1, let pageLoads = (jsonContent[0] as? NSDictionary)?["m_page_loads"] as? Int {
hour0 = pageLoads
}
This is saying "If the time of day is >= 1, and we're able to get a page load for this day, then set that value to pageLoads
, and then set hour0
to pageloads
"
The reason this is safer is because you have two as!
operators, which are forcing a conversion to NSDictionary
and Int
, respectively. If jsonContent[n]
isn't present, or if it's present but doesn't contain an Int for m_page_loads
, then this will throw an error. My safer method uses as?
for both conversions, meaning the following line:
(jsonContent[0] as? NSDictionary)?["m_page_loads"] as? Int
Will return nil
if the conversions can't be performed.
Also, instead of writing each hour out individually, another solution would be to loop through all of the hours in the JSON and append them to an array representing the page loads her hour:
var pageLoadsPerHour = [Int]()
for hour in jsonContent {
if let pageLoads = (hour as? NSDictionary)?["m_page_loads"] as? Int {
pageLoadsPerHour.append(pageLoads)
}
}
Hope this helps.
Upvotes: 1