解析json并使用核心数据保存swift 2.0最佳实践



我想使用核心数据从json文件下载、解析和保存数据。一般来说,我的代码可以工作,但当json的内容不如预期时,我会遇到问题。也许有人可以为更好的方法提供一些建议。这是我的代码:

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

下面是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
}
]
}
]
}

我的问题是,很少会发生一天中有一个或多个小时没有结果的情况。在这种情况下,我计算json中项目数量的基本方法失败了。有人能给我一个更好的方法来避免这个问题的建议吗?

我目前使用的是Xcode 7.2,并用swift2编写代码。

请不要太苛刻。正如你所猜测的,我并不是一个真正的开发者,对swift也完全陌生。

br

尼古拉

不要像这样写你的小时比较:

if (currentDayTime >= 1) {
  hour0 = (jsonContent[0] as! NSDictionary) ["m_page_loads"] as! Int
}

一种更安全的书写方式是这样的:

if currentDayTime >= 1, let pageLoads = (jsonContent[0] as? NSDictionary)?["m_page_loads"] as? Int {
    hour0 = pageLoads
}

这意味着"如果一天中的时间>=1,并且我们能够获得当天的页面加载,那么将该值设置为pageLoads,然后将hour0设置为pageloads"

这样做更安全的原因是有两个as!运算符,它们分别强制转换为NSDictionaryInt。如果jsonContent[n]不存在,或者它存在但不包含m_page_loads的Int,那么这将引发错误。我的更安全的方法对两种转换都使用as?,这意味着以下行:

(jsonContent[0] as? NSDictionary)?["m_page_loads"] as? Int

如果无法执行转换,将返回nil


此外,另一种解决方案是循环JSON中的所有小时,并将它们附加到表示页面加载小时的数组中,而不是单独写出每个小时:

var pageLoadsPerHour = [Int]()
for hour in jsonContent {
    if let pageLoads = (hour as? NSDictionary)?["m_page_loads"] as? Int {
        pageLoadsPerHour.append(pageLoads)
    }
}

希望这能有所帮助。

最新更新