Nikolay
Nikolay

Reputation: 77

parsing json and save with core data swift 2.0 best practise

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

Answers (1)

Mike Buss
Mike Buss

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

Related Questions