2016-05-01 10 views
3

コアデータを使用してjsonファイルからデータをダウンロード、解析、保存します。一般的に私のコードは動作しますが、jsonの内容が予期していない場合、私は問題にぶつかります。たぶん誰かがより良いアプローチのためのアドバイスをすることができます。ここに私のコードは次のとおりです。ここでjsonを解析してcore data swift 2.0で保存するベストプラクティス

//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 
} 
] 
} 
] 
} 

私の問題は非常にまれに、その日の1時間以上何も結果が存在しないことが起こりできないということです。この場合、jsonのアイテム数をカウントする基本的な方法は失敗します。誰も私にこの問題を回避するより良いアプローチの提案を与えることができますか?

私は現在Xcode 7.2を使用しており、swift2で自分のコードを書いています。

厳しくしないでください。あなたが推測できるように、私は本当に開発者ではなく、まったく新しいものです。

BR

ニコライ

+0

"jsonは期待通りではありません"。誰がjsonの内容を担当しているのですか? – Gruntcakes

+0

ファイルはREST APIによって生成されます。私は1日のうちの何時間でもいつもエントリーがあると思っていました。しかし、1時間にヒットがなかった場合、結び目全体が失われています(d時間のイベント、mページの読み込み) – Nikolay

答えて

1

代わりにあなたの時間を書いている。このような比較:

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

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

それらを書くためのより安全な方法は、このようなものになるだろう

これは、「一日の時間が> = 1である、と私たちはこの日のために、ページの読み込みを得ることができるしている、そしてpageLoadsにその値を設定し、次の2つを持っているので、これは安全です」

理由があるpageloadshour0を設定as!演算子は、それぞれNSDictionaryIntへの変換を強制します。 jsonContent[n]が存在しない場合、または存在するがm_page_loadsのIntが含まれていない場合は、エラーが発生します。変換が実行できない場合

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

nilを返します。私のより安全な方法は、次の行を意味し、両方の変換にas?を使用しています。


また、代わりに個別に時間を書き込むので、別の解決策は、JSONに時間のすべてをループになり、ページを表す配列にそれらを追加し、彼女の時間をロードします。

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

これが役立つことを願っています。

+0

こんにちはマイク、あなたのヒントのおかげで。私はこれが私を助け、コードをより安定したものにすると思っています;-)私は問題をできるだけ早く修正し、結果に別のコメントを書きます。 – Nikolay

+0

こんにちはマイク、ありがとう。あなたの提案は非常に役に立ち、私のバグは解決されました。乾杯 – Nikolay