Sync.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // Copyright (C) 2016 Inigo Valentin
  2. //
  3. // This file is part of the Gasteizko Margolariak IOS app.
  4. //
  5. // The Gasteizko Margolariak IOS app is free software: you can
  6. // redistribute it and/or modify it under the terms of the
  7. // GNU General Public License as published by the Free Software
  8. // Foundation, either version 3 of the License, or (at your
  9. // option) any later version.
  10. //
  11. // The Gasteizko Margolariak IOS app is distributed in the
  12. // hope that it will be useful, but WITHOUT ANY WARRANTY;
  13. // without even the implied warranty of MERCHANTABILITY or
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  15. // Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public
  18. // License along with the Gasteizko Margolariak IOS app.
  19. // If not, see <http://www.gnu.org/licenses/>.
  20. import Foundation
  21. import CoreData
  22. import UIKit
  23. /**
  24. Class to handle server sync.
  25. */
  26. class Sync{
  27. var cnt: NSManagedObjectContext
  28. /**
  29. Starts the sync process.
  30. */
  31. init(cnt: NSManagedObjectContext){
  32. self.cnt = cnt
  33. let url = buildUrl();
  34. sync(url: url)
  35. }
  36. /**
  37. Builds the URL to perform the sync against.
  38. :returns: The URL.
  39. */
  40. func buildUrl() -> URL{
  41. let url = URL(string: "https://margolariak.com/API/v1/sync.php?client=com.margolariak.app")
  42. //TODO add parameters
  43. return url!
  44. }
  45. /**
  46. Performs an asynchronous sync.
  47. It fethes the info from the server and stores as Core Data
  48. :param: url The url to sync.
  49. */
  50. func sync(url: URL){
  51. //Synchronously get data
  52. let task = URLSession.shared.dataTask(with: url) { data, response, error in
  53. guard error == nil else {
  54. print("error")
  55. return
  56. }
  57. guard let data = data else {
  58. print("Data is empty")
  59. return
  60. }
  61. print("Got the Sync JSON")
  62. var strData = String(data:data, encoding: String.Encoding.utf8)
  63. let dataIdx = strData?.indexOf(target: "{\"data\"")
  64. strData = strData!.subStr(start: dataIdx!, end: strData!.length - 1)
  65. //TODO: do something with versions
  66. //Get tables
  67. let dataActivity : [String] = self.getTable(data: strData!, table: "activity")
  68. //let dataActivityComment : [String] = self.getTable(data: strData!, table: "activity_comment")
  69. //let dataActivityImage : [String] = self.getTable(data: strData!, table: "activity_image")
  70. //let dataActivityTag : [String] = self.getTable(data: strData!, table: "activity_tag")
  71. //let dataAlbum : [String] = self.getTable(data: strData!, table: "album")
  72. //let dataFestival : [String] = self.getTable(data: strData!, table: "festival")
  73. //let dataFestivalDay : [String] = self.getTable(data: strData!, table: "festival_day")
  74. //let dataFestivalEvent : [String] = self.getTable(data: strData!, table: "festival_event")
  75. //let dataFestivalEventImage : [String] = self.getTable(data: strData!, table: "festival_event_image")
  76. //let dataFestivalOffer : [String] = self.getTable(data: strData!, table: "festival_offer")
  77. //let dataPeople : [String] = self.getTable(data: strData!, table: "people")
  78. //let dataPhoto : [String] = self.getTable(data: strData!, table: "photo")
  79. //let dataPhotoAlbum : [String] = self.getTable(data: strData!, table: "photo_album")
  80. //let dataPhotoComment : [String] = self.getTable(data: strData!, table: "photo_comment")
  81. //let dataPlace : [String] = self.getTable(data: strData!, table: "place")
  82. //let dataPost : [String] = self.getTable(data: strData!, table: "post")
  83. //let dataPostComment : [String] = self.getTable(data: strData!, table: "post_comment")
  84. //let dataPostImage : [String] = self.getTable(data: strData!, table: "post_image")
  85. //let dataPostTag : [String] = self.getTable(data: strData!, table: "post_tag")
  86. //let dataSponsor : [String] = self.getTable(data: strData!, table: "sponsor")
  87. //One by one, save the received data
  88. self.saveTableActivity(entries : dataActivity)
  89. //TEST
  90. let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
  91. let appDelegate = UIApplication.shared.delegate as! AppDelegate
  92. context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
  93. let fetchRequest: NSFetchRequest<Activity> = Activity.fetchRequest()
  94. do {
  95. //go get the results
  96. let searchResults = try context.fetch(fetchRequest)
  97. //I like to check the size of the returned results!
  98. print ("num of results = \(searchResults.count)")
  99. //You need to convert to NSManagedObject to use 'for' loops
  100. for trans in searchResults as [NSManagedObject] {
  101. //get the Key Value pairs (although there may be a better way to do that...
  102. print("\(trans.value(forKey: "permalink"))")
  103. }
  104. } catch {
  105. print("Error with request: \(error)")
  106. }
  107. }
  108. task.resume()
  109. }
  110. func getTable(data: String, table: String) -> [String]{
  111. //Does the table exists?
  112. if data.indexOf(target: table) == nil{
  113. print("No data in table \(table)")
  114. return [String]()
  115. }
  116. let iS : Int? = data.indexOf(target: table)
  117. var str = data.subStr(start: iS!, end: data.length - 1)
  118. let iE : Int? = str.indexOf(target: "}]}")!
  119. str = str.subStr(start: 0, end: iE!)
  120. str = str.subStr(start: table.length + 3,end: str.length - 1)
  121. //Separate the entries
  122. var entries : [String] = str.components(separatedBy: "},{")
  123. //Modify the first and the last one to remove bracers
  124. entries[0] = entries[0].subStr(start: 1, end: entries[0].length - 1)
  125. entries[entries.count - 1] = entries[entries.count - 1].subStr(start: 0, end: entries[entries.count - 1].length - 2)
  126. //Return the array
  127. return entries
  128. }
  129. func saveTableActivity(entries : [String]){
  130. let dateFormatter = DateFormatter()
  131. dateFormatter.timeZone = TimeZone.ReferenceType.local
  132. //let context = self.cnt //getContext()
  133. //Set up context
  134. let appDelegate = UIApplication.shared.delegate as! AppDelegate
  135. let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
  136. context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
  137. let entity = NSEntityDescription.entity(forEntityName: "Activity", in: context)
  138. var transc: NSManagedObject
  139. //Delete all previous entries
  140. let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Activity")
  141. let request = NSBatchDeleteRequest(fetchRequest: fetch)
  142. do {
  143. try context.execute(request)
  144. } catch let error as NSError {
  145. print("Could not clean up Activity table: \(error), \(error.userInfo)")
  146. } catch {
  147. }
  148. //Loop new entries
  149. for entry in entries{
  150. //Get id
  151. var str = entry
  152. let id : Int = Int(str.subStr(start : str.indexOf(target : "\"id\":")! + 6, end : str.indexOf(target : ",\"")! - 2))!
  153. //print("Id: \(id)")
  154. //Get permalink
  155. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  156. let permalink : String = str.subStr(start : str.indexOf(target : "\"permalink\":")! + 13, end : str.indexOf(target : ",\"")! - 2)
  157. //print("Permalink: \(permalink)")
  158. //Get date
  159. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  160. dateFormatter.dateFormat = "yyyy-MM-dd"
  161. let date = dateFormatter.date(from : str.subStr(start : str.indexOf(target : "\"date\":")! + 8, end : str.indexOf(target : ",\"")! - 2))!
  162. //print("Date: \(date)")
  163. //Get city
  164. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  165. let city : String = str.subStr(start : str.indexOf(target : "\"city\":")! + 8, end : str.indexOf(target : ",\"")! - 2)
  166. //print("City: \(city)")
  167. //Get title_es
  168. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  169. let title_es : String = str.subStr(start : str.indexOf(target : "\"title_es\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  170. //print("Title (es): \(title_es)")
  171. //Get title_en
  172. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  173. let title_en : String = str.subStr(start : str.indexOf(target : "\"title_en\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  174. //print("Title (en): \(title_en)")
  175. //Get title_eu
  176. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  177. let title_eu : String = str.subStr(start : str.indexOf(target : "\"title_eu\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  178. //print("Title (eu): \(title_eu)")
  179. //Get text_es
  180. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  181. let text_es : String = str.subStr(start : str.indexOf(target : "\"text_es\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
  182. //print("Text (es): \(text_es)")
  183. //Get text_eu
  184. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  185. let text_eu : String = str.subStr(start : str.indexOf(target : "\"text_eu\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
  186. //print("Text (eu): \(text_eu)")
  187. //Get text_en
  188. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  189. let text_en : String = str.subStr(start : str.indexOf(target : "\"text_en\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
  190. //print("Text (en): \(text_en)")
  191. //Get after_es
  192. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  193. var after_es : String = str.subStr(start : str.indexOf(target : "\"after_es\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  194. if (after_es == "ul"){ //From "null"
  195. after_es = ""
  196. }
  197. //print("After (es): \(after_es)")
  198. //Get after_en
  199. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  200. var after_en : String = str.subStr(start : str.indexOf(target : "\"after_en\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  201. if (after_en == "ul"){ //From "null"
  202. after_en = ""
  203. }
  204. //print("After (en): \(after_en)")
  205. //Get after_eu
  206. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  207. var after_eu : String = str.subStr(start : str.indexOf(target : "\"after_eu\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  208. if (after_eu == "ul"){ //From "null"
  209. after_eu = ""
  210. }
  211. //print("After (eu): \(after_eu)")
  212. //Get price
  213. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  214. let price : Int = Int(str.subStr(start : str.indexOf(target : "\"price\":")! + 9, end : str.indexOf(target : ",\"")! - 2))!
  215. //print("Price: \(price)")
  216. //Get inscription
  217. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  218. let inscription : Int = Int(str.subStr(start : str.indexOf(target : "\"inscription\":")! + 15, end : str.indexOf(target : ",\"")! - 2))!
  219. //print("Inscription: \(inscription)")
  220. //Get max_people
  221. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  222. let maxPeople : Int = Int(str.subStr(start : str.indexOf(target : "\"max_people\":")! + 14, end : str.indexOf(target : ",\"")! - 2))!
  223. //print("Max People: \(maxPeople)")
  224. //Get album
  225. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  226. let albumPre = str.subStr(start : str.indexOf(target : "\"album\":")! + 9, end : str.length - 2)
  227. var album = -1
  228. if (albumPre != "ul"){ //From "null"
  229. album = Int(albumPre)!
  230. }
  231. //print("Album: \(album)")
  232. //Skipping dtime
  233. //Skipping comments
  234. //TODO: Save CoreData
  235. transc = NSManagedObject(entity: entity!, insertInto: context)
  236. //set the entity values
  237. transc.setValue(id, forKey: "id")
  238. transc.setValue(permalink, forKey: "permalink")
  239. transc.setValue(date, forKey: "date")
  240. transc.setValue(city, forKey: "city")
  241. transc.setValue(title_es, forKey: "title_es")
  242. transc.setValue(title_en, forKey: "title_en")
  243. transc.setValue(title_eu, forKey: "title_eu")
  244. transc.setValue(text_es, forKey: "text_es")
  245. transc.setValue(text_en, forKey: "text_en")
  246. transc.setValue(text_eu, forKey: "text_eu")
  247. transc.setValue(after_es, forKey: "after_es")
  248. transc.setValue(after_en, forKey: "after_en")
  249. transc.setValue(after_eu, forKey: "after_eu")
  250. transc.setValue(price, forKey: "price")
  251. transc.setValue(inscription, forKey: "inscription")
  252. transc.setValue(maxPeople, forKey: "max_people")
  253. if (album != -1){
  254. transc.setValue(album, forKey: "album")
  255. }
  256. do {
  257. try context.save()
  258. } catch let error as NSError {
  259. print("Could not store Activity with id \(id) \(error), \(error.userInfo)")
  260. } catch {
  261. }
  262. }
  263. }
  264. }