[ABANDONED] Mastodon iOS client.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
7.3 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. //
  2. // InstancesDataManager.swift
  3. // elpha-ios
  4. //
  5. // Created by Dwayne Harris on 9/18/18.
  6. // Copyright © 2018 Elpha. All rights reserved.
  7. //
  8. import Alamofire
  9. import CoreData
  10. import UIKit
  11. class InstancesDataManager {
  12. static let shared = InstancesDataManager()
  13. let fetchLimit = 20
  14. var instances: [ISInstanceMO] = []
  15. var nextID: String?
  16. var finished = false
  17. func upsertLanguage(string: String) -> ISLanguageMO? {
  18. let context = CoreDataManager.shared.context
  19. context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
  20. let request = NSFetchRequest<ISLanguageMO>(entityName: "ISLanguage")
  21. request.predicate = NSPredicate(format: "id == %@", string)
  22. do {
  23. let results = try context.fetch(request)
  24. if let language = results.first {
  25. return language
  26. } else {
  27. let language = ISLanguageMO(context: context)
  28. language.id = string
  29. return language
  30. }
  31. } catch {
  32. print("\(error)")
  33. return nil
  34. }
  35. }
  36. func upsertCategory(string: String) -> ISCategoryMO? {
  37. let context = CoreDataManager.shared.context
  38. context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
  39. let request = NSFetchRequest<ISCategoryMO>(entityName: "ISCategory")
  40. request.predicate = NSPredicate(format: "id == %@", string)
  41. do {
  42. let results = try context.fetch(request)
  43. if let category = results.first {
  44. return category
  45. } else {
  46. let category = ISCategoryMO(context: context)
  47. category.id = string
  48. return category
  49. }
  50. } catch {
  51. print("\(error)")
  52. return nil
  53. }
  54. }
  55. func setAttributes(on instance: ISInstanceMO, with attributes: [String: Any]) {
  56. guard let id = attributes["id"] as? String, let name = attributes["name"] as? String else {
  57. return
  58. }
  59. let dateFormatter = DateFormatter()
  60. dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
  61. dateFormatter.locale = Locale(identifier: "en_US_POSIX")
  62. instance.id = id
  63. instance.name = name
  64. instance.url = URL(string: "https://\(name)")!
  65. instance.uptime = attributes["uptime"] as! Int32
  66. instance.up = attributes["up"] as! Bool
  67. instance.dead = attributes["dead"] as! Bool
  68. instance.version = attributes["version"] as? String
  69. instance.ipv6 = attributes["ipv6"] as! Bool
  70. instance.users = Int64(attributes["users"] as! String)!
  71. instance.statuses = Int64(attributes["statuses"] as! String)!
  72. instance.connections = Int64(attributes["connections"] as! String)!
  73. instance.openRegistrations = attributes["open_registrations"] as! Bool
  74. instance.fetchedAt = Date()
  75. if let activeUsers = attributes["active_users"] as? Int64 {
  76. instance.activeUsers = activeUsers
  77. }
  78. if let updatedAt = attributes["updated_at"] as? String {
  79. instance.updatedAt = dateFormatter.date(from: updatedAt)
  80. }
  81. if let checkedAt = attributes["checked_at"] as? String {
  82. instance.checkedAt = dateFormatter.date(from: checkedAt)
  83. }
  84. if let thumbnail = attributes["thumbnail"] as? String {
  85. instance.thumbnail = URL(string: thumbnail)!
  86. }
  87. if let info = attributes["info"] as? [String: Any] {
  88. instance.shortDesc = info["short_description"] as? String
  89. instance.fullDescription = info["full_description"] as? String
  90. instance.topic = info["topic"] as? String
  91. for language in info["languages"] as! [String] {
  92. if let l = upsertLanguage(string: language) {
  93. instance.mutableSetValue(forKey: "languages").add(l)
  94. }
  95. }
  96. for category in info["categories"] as! [String] {
  97. if let c = upsertCategory(string: category) {
  98. instance.mutableSetValue(forKey: "categories").add(c)
  99. }
  100. }
  101. }
  102. }
  103. func clearInstances() {
  104. let request = NSFetchRequest<ISInstanceMO>(entityName: "ISInstance")
  105. do {
  106. let instances = try CoreDataManager.shared.context.fetch(request)
  107. instances.forEach { instance in
  108. CoreDataManager.shared.context.delete(instance)
  109. }
  110. } catch {
  111. print("\(error)")
  112. }
  113. }
  114. func reloadInstances(completion: @escaping (Error?) -> Void) {
  115. nextID = nil
  116. finished = false
  117. loadInstances(completion: completion)
  118. }
  119. func loadInstances(completion: @escaping (Error?) -> Void) {
  120. var params = [
  121. "count=\(fetchLimit)",
  122. "sort_by=users",
  123. "sort_order=desc",
  124. "include_closed=true",
  125. "include_down=false",
  126. ]
  127. if let nextID = nextID {
  128. params.append("min_id=\(nextID)")
  129. }
  130. let requestURL = "\(Config.instancesServiceURL)\(Config.instancesServiceListEndpoint)?\(params.joined(separator: "&"))"
  131. let headers: HTTPHeaders = ["Authorization": "Bearer \(Config.instancesServiceSecret)"]
  132. Alamofire.request(requestURL, headers: headers).validate().responseJSON { response in
  133. switch response.result {
  134. case .success(let value):
  135. guard let result = value as? [String: Any],
  136. let pagination = result["pagination"] as? [String: Any],
  137. let instances = result["instances"] as? [Any] else {
  138. completion(NSError())
  139. return
  140. }
  141. if let nextID = pagination["next_id"] as? String {
  142. self.nextID = nextID
  143. } else {
  144. self.nextID = nil
  145. self.finished = true
  146. }
  147. do {
  148. for case let instance as [String: Any] in instances {
  149. if let id = instance["id"] as? String {
  150. let request = NSFetchRequest<ISInstanceMO>(entityName: "ISInstance")
  151. request.predicate = NSPredicate(format: "id == %@", id)
  152. let results: [ISInstanceMO] = try CoreDataManager.shared.context.fetch(request)
  153. if let i = results.first {
  154. self.setAttributes(on: i, with: instance)
  155. } else {
  156. let i = ISInstanceMO(context: CoreDataManager.shared.context)
  157. self.setAttributes(on: i, with: instance)
  158. }
  159. }
  160. }
  161. CoreDataManager.shared.saveContext()
  162. completion(nil)
  163. } catch {
  164. completion(error)
  165. return
  166. }
  167. case .failure(let error):
  168. completion(error)
  169. }
  170. }
  171. }
  172. }