Sync.swift 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  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. /**
  28. Starts the sync process.
  29. */
  30. init(){
  31. let url = buildUrl();
  32. sync(url: url)
  33. }
  34. /**
  35. Builds the URL to perform the sync against.
  36. :returns: The URL.
  37. */
  38. func buildUrl() -> URL{
  39. let url = URL(string: "https://margolariak.com/API/v1/sync.php?client=com.margolariak.app")
  40. //TODO add parameters
  41. return url!
  42. }
  43. /**
  44. Performs an asynchronous sync.
  45. It fethes the info from the server and stores as Core Data
  46. :param: url The url to sync.
  47. */
  48. func sync(url: URL){
  49. //Synchronously get data
  50. let task = URLSession.shared.dataTask(with: url) { data, response, error in
  51. guard error == nil else {
  52. print("error")
  53. return
  54. }
  55. guard let data = data else {
  56. print("Data is empty")
  57. return
  58. }
  59. print("Got the Sync JSON")
  60. var strData = String(data:data, encoding: String.Encoding.utf8)
  61. let dataIdx = strData?.indexOf(target: "{\"data\"")
  62. strData = strData!.subStr(start: dataIdx!, end: strData!.length - 1)
  63. //TODO: do something with versions
  64. //Get tables
  65. let dataActivity : [String] = self.getTable(data: strData!, table: "activity")
  66. let dataActivityComment : [String] = self.getTable(data: strData!, table: "activity_comment")
  67. let dataActivityImage : [String] = self.getTable(data: strData!, table: "activity_image")
  68. let dataActivityTag : [String] = self.getTable(data: strData!, table: "activity_tag")
  69. //let dataAlbum : [String] = self.getTable(data: strData!, table: "album")
  70. //let dataFestival : [String] = self.getTable(data: strData!, table: "festival")
  71. //let dataFestivalDay : [String] = self.getTable(data: strData!, table: "festival_day")
  72. //let dataFestivalEvent : [String] = self.getTable(data: strData!, table: "festival_event")
  73. //let dataFestivalEventImage : [String] = self.getTable(data: strData!, table: "festival_event_image")
  74. //let dataFestivalOffer : [String] = self.getTable(data: strData!, table: "festival_offer")
  75. //let dataPeople : [String] = self.getTable(data: strData!, table: "people")
  76. //let dataPhoto : [String] = self.getTable(data: strData!, table: "photo")
  77. //let dataPhotoAlbum : [String] = self.getTable(data: strData!, table: "photo_album")
  78. //let dataPhotoComment : [String] = self.getTable(data: strData!, table: "photo_comment")
  79. //let dataPlace : [String] = self.getTable(data: strData!, table: "place")
  80. //let dataPost : [String] = self.getTable(data: strData!, table: "post")
  81. //let dataPostComment : [String] = self.getTable(data: strData!, table: "post_comment")
  82. //let dataPostImage : [String] = self.getTable(data: strData!, table: "post_image")
  83. //let dataPostTag : [String] = self.getTable(data: strData!, table: "post_tag")
  84. //let dataSponsor : [String] = self.getTable(data: strData!, table: "sponsor")
  85. //One by one, save the received data
  86. self.saveTableActivity(entries : dataActivity)
  87. self.saveTableActivityComment(entries : dataActivityComment)
  88. self.saveTableActivityImage(entries : dataActivityImage)
  89. self.saveTableActivityTag(entries : dataActivityTag)
  90. //TODO: Tester, Debug only
  91. // Test if a entity has entries
  92. let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
  93. let appDelegate = UIApplication.shared.delegate as! AppDelegate
  94. context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
  95. let fetchRequest: NSFetchRequest<Activity_comment> = Activity_comment.fetchRequest()
  96. do {
  97. //go get the results
  98. let searchResults = try context.fetch(fetchRequest)
  99. //I like to check the size of the returned results!
  100. print ("num of results = \(searchResults.count)")
  101. //You need to convert to NSManagedObject to use 'for' loops
  102. for trans in searchResults as [NSManagedObject] {
  103. //get the Key Value pairs (although there may be a better way to do that...
  104. print("\(trans.value(forKey: "id"))")
  105. }
  106. } catch {
  107. print("Error with request: \(error)")
  108. }
  109. //End tester
  110. }
  111. task.resume()
  112. }
  113. func getTable(data: String, table: String) -> [String]{
  114. //Does the table exists?
  115. if data.indexOf(target: table) == nil{
  116. print("No data in table \(table)")
  117. return [String]()
  118. }
  119. let iS : Int? = data.indexOf(target: table)
  120. var str = data.subStr(start: iS!, end: data.length - 1)
  121. let iE : Int? = str.indexOf(target: "}]}")!
  122. str = str.subStr(start: 0, end: iE!)
  123. str = str.subStr(start: table.length + 3,end: str.length - 1)
  124. //Separate the entries
  125. var entries : [String] = str.components(separatedBy: "},{")
  126. //Modify the first and the last one to remove bracers
  127. entries[0] = entries[0].subStr(start: 1, end: entries[0].length - 1)
  128. entries[entries.count - 1] = entries[entries.count - 1].subStr(start: 0, end: entries[entries.count - 1].length - 2)
  129. //Return the array
  130. return entries
  131. }
  132. func saveTableActivity(entries : [String]){
  133. let dateFormatter = DateFormatter()
  134. dateFormatter.timeZone = TimeZone.ReferenceType.local
  135. //Set up context
  136. let appDelegate = UIApplication.shared.delegate as! AppDelegate
  137. let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
  138. context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
  139. let entity = NSEntityDescription.entity(forEntityName: "Activity", in: context)
  140. var row: NSManagedObject
  141. //Delete all previous entries
  142. let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Activity")
  143. let request = NSBatchDeleteRequest(fetchRequest: fetch)
  144. do {
  145. try context.execute(request)
  146. } catch let error as NSError {
  147. print("Could not clean up Activity entity: \(error), \(error.userInfo)")
  148. } catch {
  149. }
  150. //Loop new entries
  151. for entry in entries{
  152. //Get id
  153. var str = entry
  154. let id : Int = Int(str.subStr(start : str.indexOf(target : "\"id\":")! + 6, end : str.indexOf(target : ",\"")! - 2))!
  155. //Get permalink
  156. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  157. let permalink : String = str.subStr(start : str.indexOf(target : "\"permalink\":")! + 13, end : str.indexOf(target : ",\"")! - 2)
  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. //Get city
  163. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  164. let city : String = str.subStr(start : str.indexOf(target : "\"city\":")! + 8, end : str.indexOf(target : ",\"")! - 2)
  165. //Get title_es
  166. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  167. let title_es : String = str.subStr(start : str.indexOf(target : "\"title_es\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  168. //Get title_en
  169. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  170. let title_en : String = str.subStr(start : str.indexOf(target : "\"title_en\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  171. //Get title_eu
  172. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  173. let title_eu : String = str.subStr(start : str.indexOf(target : "\"title_eu\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  174. //Get text_es
  175. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  176. let text_es : String = str.subStr(start : str.indexOf(target : "\"text_es\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
  177. //Get text_eu
  178. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  179. let text_eu : String = str.subStr(start : str.indexOf(target : "\"text_eu\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
  180. //Get text_en
  181. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  182. let text_en : String = str.subStr(start : str.indexOf(target : "\"text_en\":")! + 11, end : str.indexOf(target : ",\"")! - 2)
  183. //Get after_es
  184. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  185. var after_es : String = str.subStr(start : str.indexOf(target : "\"after_es\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  186. if (after_es == "ul"){ //From "null"
  187. after_es = ""
  188. }
  189. //Get after_en
  190. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  191. var after_en : String = str.subStr(start : str.indexOf(target : "\"after_en\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  192. if (after_en == "ul"){ //From "null"
  193. after_en = ""
  194. }
  195. //Get after_eu
  196. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  197. var after_eu : String = str.subStr(start : str.indexOf(target : "\"after_eu\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  198. if (after_eu == "ul"){ //From "null"
  199. after_eu = ""
  200. }
  201. //Get price
  202. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  203. let price : Int = Int(str.subStr(start : str.indexOf(target : "\"price\":")! + 9, end : str.indexOf(target : ",\"")! - 2))!
  204. //print("Price: \(price)")
  205. //Get inscription
  206. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  207. let inscription : Int = Int(str.subStr(start : str.indexOf(target : "\"inscription\":")! + 15, end : str.indexOf(target : ",\"")! - 2))!
  208. //Get max_people
  209. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  210. let maxPeoplePre : String = str.subStr(start : str.indexOf(target : "\"max_people\":")! + 14, end : str.indexOf(target : ",")! - 2)
  211. var maxPeople = -1
  212. if (maxPeoplePre != "ul"){ //From "null"
  213. maxPeople = Int(maxPeoplePre)!
  214. }
  215. //Get album
  216. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  217. let albumPre = str.subStr(start : str.indexOf(target : "\"album\":")! + 9, end : str.length - 2)
  218. var album = -1
  219. if (albumPre != "ul"){ //From "null"
  220. album = Int(albumPre)!
  221. }
  222. //Skipping dtime
  223. //Skipping comments
  224. //Save CoreData
  225. row = NSManagedObject(entity: entity!, insertInto: context)
  226. //set the entity values
  227. row.setValue(id, forKey: "id")
  228. row.setValue(permalink, forKey: "permalink")
  229. row.setValue(date, forKey: "date")
  230. row.setValue(city, forKey: "city")
  231. row.setValue(title_es, forKey: "title_es")
  232. row.setValue(title_en, forKey: "title_en")
  233. row.setValue(title_eu, forKey: "title_eu")
  234. row.setValue(text_es, forKey: "text_es")
  235. row.setValue(text_en, forKey: "text_en")
  236. row.setValue(text_eu, forKey: "text_eu")
  237. row.setValue(after_es, forKey: "after_es")
  238. row.setValue(after_en, forKey: "after_en")
  239. row.setValue(after_eu, forKey: "after_eu")
  240. row.setValue(price, forKey: "price")
  241. row.setValue(inscription, forKey: "inscription")
  242. row.setValue(maxPeople, forKey: "max_people")
  243. if (album != -1){
  244. row.setValue(album, forKey: "album")
  245. }
  246. do {
  247. try context.save()
  248. } catch let error as NSError {
  249. print("Could not store Activity with id \(id) \(error), \(error.userInfo)")
  250. } catch {
  251. }
  252. }
  253. }
  254. func saveTableActivityComment(entries : [String]){
  255. let dateFormatter = DateFormatter()
  256. dateFormatter.timeZone = TimeZone.ReferenceType.local
  257. //Set up context
  258. let appDelegate = UIApplication.shared.delegate as! AppDelegate
  259. let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
  260. context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
  261. let entity = NSEntityDescription.entity(forEntityName: "Activity_comment", in: context)
  262. var row: NSManagedObject
  263. //Delete all previous entries
  264. let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Activity_comment")
  265. let request = NSBatchDeleteRequest(fetchRequest: fetch)
  266. do {
  267. try context.execute(request)
  268. } catch let error as NSError {
  269. print("Could not clean up Activity_comment entity: \(error), \(error.userInfo)")
  270. } catch {
  271. }
  272. //Loop new entries
  273. for entry in entries{
  274. //Get id
  275. var str = entry
  276. let id : Int = Int(str.subStr(start : str.indexOf(target : "\"id\":")! + 6, end : str.indexOf(target : ",\"")! - 2))!
  277. //Get activity
  278. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  279. let activity : String = str.subStr(start : str.indexOf(target : "\"activity\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  280. //Get text
  281. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  282. let text : String = str.subStr(start : str.indexOf(target : "\"text\":")! + 8, end : str.indexOf(target : ",\"")! - 2)
  283. //Get dtime
  284. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  285. dateFormatter.dateFormat = "yyyy-MM-dd"
  286. let dtime = dateFormatter.date(from : str.subStr(start : str.indexOf(target : "\"dtime\":")! + 9, end : str.indexOf(target : ",\"")! - 2))!
  287. //Get username
  288. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  289. let username : String = str.subStr(start : str.indexOf(target : "\"username\":")! + 12, end : str.indexOf(target : ",\"")! - 2)
  290. //Get lang
  291. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  292. let lang : String = str.subStr(start : str.indexOf(target : "\"lang\":")! + 8, end : str.length - 1)
  293. //Save CoreData
  294. row = NSManagedObject(entity: entity!, insertInto: context)
  295. row.setValue(id, forKey: "id")
  296. row.setValue(activity, forKey: "activity")
  297. row.setValue(text, forKey: "text")
  298. row.setValue(dtime, forKey: "dtime")
  299. row.setValue(username, forKey: "username")
  300. row.setValue(lang, forKey: "lang")
  301. do {
  302. try context.save()
  303. } catch let error as NSError {
  304. print("Could not store Activity_comment with id \(id) \(error), \(error.userInfo)")
  305. } catch {
  306. }
  307. }
  308. }
  309. func saveTableActivityImage(entries : [String]){
  310. //Set up context
  311. let appDelegate = UIApplication.shared.delegate as! AppDelegate
  312. let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
  313. context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
  314. let entity = NSEntityDescription.entity(forEntityName: "Activity_image", in: context)
  315. var row: NSManagedObject
  316. //Delete all previous entries
  317. let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Activity_image")
  318. let request = NSBatchDeleteRequest(fetchRequest: fetch)
  319. do {
  320. try context.execute(request)
  321. } catch let error as NSError {
  322. print("Could not clean up Activity_comment entity: \(error), \(error.userInfo)")
  323. } catch {
  324. }
  325. //Loop new entries
  326. for entry in entries{
  327. //Get id
  328. var str = entry
  329. let id : Int = Int(str.subStr(start : str.indexOf(target : "\"id\":")! + 6, end : str.indexOf(target : ",\"")! - 2))!
  330. //Get activity
  331. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  332. let activity : Int = Int(str.subStr(start : str.indexOf(target : "\"activity\":")! + 12, end : str.indexOf(target : ",\"")! - 2))!
  333. //Get image
  334. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  335. let image : String = str.subStr(start : str.indexOf(target : "\"image\":")! + 9, end : str.indexOf(target : ",\"")! - 2)
  336. //Get idx
  337. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  338. let idx : Int = Int(str.subStr(start : str.indexOf(target : "\"idx\":")! + 7, end : str.length - 2))!
  339. //Save CoreData
  340. row = NSManagedObject(entity: entity!, insertInto: context)
  341. row.setValue(id, forKey: "id")
  342. row.setValue(activity, forKey: "activity")
  343. row.setValue(image, forKey: "image")
  344. row.setValue(idx, forKey: "idx")
  345. do {
  346. try context.save()
  347. } catch let error as NSError {
  348. print("Could not store Activity_image with id \(id) \(error), \(error.userInfo)")
  349. } catch {
  350. }
  351. }
  352. }
  353. func saveTableActivityTag(entries : [String]){
  354. //Set up context
  355. let appDelegate = UIApplication.shared.delegate as! AppDelegate
  356. let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
  357. context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
  358. let entity = NSEntityDescription.entity(forEntityName: "Activity_tag", in: context)
  359. var row: NSManagedObject
  360. //Delete all previous entries
  361. let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Activity_tag")
  362. let request = NSBatchDeleteRequest(fetchRequest: fetch)
  363. do {
  364. try context.execute(request)
  365. } catch let error as NSError {
  366. print("Could not clean up Activity_tag entity: \(error), \(error.userInfo)")
  367. } catch {
  368. }
  369. //Loop new entries
  370. for entry in entries{
  371. //Get activity
  372. var str = entry
  373. let activity : Int = Int(str.subStr(start : str.indexOf(target : "\"activity\":")! + 12, end : str.indexOf(target : ",\"")! - 2))!
  374. //Get tag
  375. str = str.subStr(start : str.indexOf(target : ",\"")! + 1, end : str.length - 1)
  376. let tag : String = str.subStr(start : str.indexOf(target : "\"tag\":")! + 7, end : str.length - 1)
  377. //Save CoreData
  378. row = NSManagedObject(entity: entity!, insertInto: context)
  379. row.setValue(activity, forKey: "activity")
  380. row.setValue(tag, forKey: "tag")
  381. do {
  382. try context.save()
  383. } catch let error as NSError {
  384. print("Could not store Activity_tag for activity: \(activity), tag: \(tag). Error: \(error), \(error.userInfo)")
  385. } catch {
  386. }
  387. }
  388. }
  389. }