Dwayne Harris
6 years ago
12 changed files with 370 additions and 315 deletions
-
26elpha-ios.xcodeproj/project.pbxproj
-
8elpha-ios.xcodeproj/xcuserdata/Dwayne.xcuserdatad/xcschemes/xcschememanagement.plist
-
47elpha-ios/Base.lproj/Main.storyboard
-
52elpha-ios/Elpha.xcdatamodeld/Elpha.xcdatamodel/contents
-
16elpha-ios/InstanceViewController.swift
-
235elpha-ios/InstancesDataManager.swift
-
13elpha-ios/InstancesNavigationController.swift
-
15elpha-ios/InstancesTableView.swift
-
4elpha-ios/InstancesTableViewCell.swift
-
191elpha-ios/InstancesTableViewController.swift
-
56elpha-ios/WebViewController.swift
-
22elpha-ios/WebViewHelper.swift
@ -0,0 +1,235 @@ |
|||
// |
|||
// InstancesDataManager.swift |
|||
// elpha-ios |
|||
// |
|||
// Created by Dwayne Harris on 9/18/18. |
|||
// Copyright © 2018 Elpha. All rights reserved. |
|||
// |
|||
|
|||
import CoreData |
|||
import Foundation |
|||
import UIKit |
|||
|
|||
class InstancesDataManager { |
|||
static let shared = InstancesDataManager() |
|||
|
|||
let instanceRequestCount = 20 |
|||
var instances: [ISInstanceMO] = [] |
|||
var finished = false |
|||
var nextID: String? = nil |
|||
|
|||
static func upsertLanguage(string: String) -> ISLanguageMO? { |
|||
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext |
|||
let request = NSFetchRequest<ISLanguageMO>(entityName: "ISLanguage") |
|||
request.predicate = NSPredicate(format: "id == %@", string) |
|||
|
|||
do { |
|||
let results: [ISLanguageMO] = try context.fetch(request) |
|||
switch results.count { |
|||
case 0: |
|||
let language = ISLanguageMO(context: context) |
|||
language.id = string |
|||
try context.save() |
|||
|
|||
return language |
|||
case 1: |
|||
return results.first |
|||
default: |
|||
print("Duplicate ISLanguage entity") |
|||
return nil |
|||
} |
|||
} catch { |
|||
print("\(error)") |
|||
return nil |
|||
} |
|||
} |
|||
|
|||
static func upsertCategory(string: String) -> ISCategoryMO? { |
|||
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext |
|||
let request = NSFetchRequest<ISCategoryMO>(entityName: "ISCategory") |
|||
request.predicate = NSPredicate(format: "id == %@", string) |
|||
|
|||
do { |
|||
let results: [ISCategoryMO] = try context.fetch(request) |
|||
switch results.count { |
|||
case 0: |
|||
let category = ISCategoryMO(context: context) |
|||
category.id = string |
|||
try context.save() |
|||
|
|||
return category |
|||
case 1: |
|||
return results.first |
|||
default: |
|||
print("Duplicate ISCategory entity") |
|||
return nil |
|||
} |
|||
} catch { |
|||
print("\(error)") |
|||
return nil |
|||
} |
|||
} |
|||
|
|||
static func setAttributes(on i: ISInstanceMO, attributes: [String: Any]) { |
|||
guard let id = attributes["id"] as? String, let name = attributes["name"] as? String else { |
|||
print("Error") |
|||
return |
|||
} |
|||
|
|||
let dateFormatter = DateFormatter() |
|||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" |
|||
dateFormatter.locale = Locale(identifier: "en_US_POSIX") |
|||
|
|||
i.id = id |
|||
i.name = name |
|||
i.url = URL(string: "https://\(name)")! |
|||
i.uptime = attributes["uptime"] as! Int32 |
|||
i.up = attributes["up"] as! Bool |
|||
i.dead = attributes["dead"] as! Bool |
|||
i.version = attributes["version"] as? String |
|||
i.ipv6 = attributes["ipv6"] as! Bool |
|||
i.users = Int64(attributes["users"] as! String)! |
|||
i.statuses = Int64(attributes["statuses"] as! String)! |
|||
i.connections = Int64(attributes["connections"] as! String)! |
|||
i.openRegistrations = attributes["open_registrations"] as! Bool |
|||
|
|||
if let activeUsers = attributes["active_users"] as? Int64 { |
|||
i.activeUsers = activeUsers |
|||
} |
|||
|
|||
if let updatedAt = attributes["updated_at"] as? String { |
|||
i.updatedAt = dateFormatter.date(from: updatedAt) |
|||
} |
|||
|
|||
if let checkedAt = attributes["checked_at"] as? String { |
|||
i.checkedAt = dateFormatter.date(from: checkedAt) |
|||
} |
|||
|
|||
if let thumbnail = attributes["thumbnail"] as? String { |
|||
i.thumbnail = URL(string: thumbnail)! |
|||
} |
|||
|
|||
if let info = attributes["info"] as? [String: Any] { |
|||
i.shortDesc = info["short_description"] as? String |
|||
i.fullDescription = info["full_description"] as? String |
|||
i.topic = info["topic"] as? String |
|||
|
|||
for language in info["languages"] as! [String] { |
|||
if let l = upsertLanguage(string: language) { |
|||
i.mutableSetValue(forKey: "languages").add(l) |
|||
} |
|||
} |
|||
|
|||
for category in info["categories"] as! [String] { |
|||
if let c = upsertCategory(string: category) { |
|||
i.mutableSetValue(forKey: "categories").add(c) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
func reloadInstances(completion: @escaping (Error?) -> Void) { |
|||
finished = false |
|||
nextID = nil |
|||
loadInstances(completion: completion) |
|||
} |
|||
|
|||
func loadInstances(completion: @escaping (Error?) -> Void) { |
|||
var params = [ |
|||
"count=\(instanceRequestCount)", |
|||
"sort_by=users", |
|||
"sort_order=desc", |
|||
"include_closed=true", |
|||
"include_down=false", |
|||
] |
|||
|
|||
if let nextID = nextID { |
|||
params.append("min_id=\(nextID)") |
|||
} |
|||
|
|||
let requestURL = "\(Config.instancesServiceUrl)\(Config.instancesServiceEndpoint)?\(params.joined(separator: "&"))" |
|||
print("loading instances: requestURL: \(requestURL)") |
|||
|
|||
var request = URLRequest(url: URL(string: requestURL)!) |
|||
request.addValue("Bearer \(Config.instancesServiceSecret)", forHTTPHeaderField: "Authorization") |
|||
|
|||
URLSession.shared.dataTask(with: request) { data, response, error in |
|||
guard error == nil else { |
|||
completion(error) |
|||
return |
|||
} |
|||
|
|||
guard let response = response as? HTTPURLResponse else { |
|||
print("No HTTP response") |
|||
completion(NSError()) |
|||
return |
|||
} |
|||
|
|||
switch response.statusCode { |
|||
case 200..<300: |
|||
guard let data = data else { |
|||
print("No HTTP response") |
|||
completion(NSError()) |
|||
return |
|||
} |
|||
|
|||
DispatchQueue.main.async { |
|||
do { |
|||
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext |
|||
let instancesResult = try JSONSerialization.jsonObject(with: data) as! [String: Any] |
|||
|
|||
if let pagination = instancesResult["pagination"] as? [String: Any] { |
|||
if let nextID = pagination["next_id"] as? String { |
|||
self.nextID = nextID |
|||
} else { |
|||
self.nextID = nil |
|||
self.finished = true |
|||
} |
|||
} |
|||
|
|||
if let instances = instancesResult["instances"] as? [Any] { |
|||
for case let instance as [String: Any] in instances { |
|||
if let id = instance["id"] as? String { |
|||
let request = NSFetchRequest<ISInstanceMO>(entityName: "ISInstance") |
|||
request.predicate = NSPredicate(format: "id == %@", id) |
|||
|
|||
let results: [ISInstanceMO] = try context.fetch(request) |
|||
|
|||
switch results.count { |
|||
case 0: |
|||
let i = ISInstanceMO(context: context) |
|||
InstancesDataManager.setAttributes(on: i, attributes: instance) |
|||
case 1: |
|||
if let i = results.first { |
|||
InstancesDataManager.setAttributes(on: i, attributes: instance) |
|||
} |
|||
default: |
|||
print("Duplicate Instance entity") |
|||
} |
|||
} |
|||
} |
|||
|
|||
do { |
|||
try context.save() |
|||
} catch { |
|||
completion(error) |
|||
return |
|||
} |
|||
} |
|||
|
|||
completion(nil) |
|||
} catch { |
|||
completion(error) |
|||
return |
|||
} |
|||
} |
|||
case 400: |
|||
print("instances.social: 400") |
|||
completion(NSError()) |
|||
default: |
|||
completion(nil) |
|||
return |
|||
} |
|||
}.resume() |
|||
} |
|||
} |
@ -1,13 +0,0 @@ |
|||
// |
|||
// InstancesNavigationController.swift |
|||
// elpha-ios |
|||
// |
|||
// Created by Dwayne Harris on 8/29/18. |
|||
// Copyright © 2018 Elpha. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
|
|||
class InstancesNavigationController: UINavigationController { |
|||
|
|||
} |
@ -1,15 +0,0 @@ |
|||
// |
|||
// InstancesTableView.swift |
|||
// elpha-ios |
|||
// |
|||
// Created by Dwayne Harris on 8/30/18. |
|||
// Copyright © 2018 Elpha. All rights reserved. |
|||
// |
|||
|
|||
import UIKit |
|||
|
|||
class InstancesTableView: UITableView { |
|||
required init?(coder aDecoder: NSCoder) { |
|||
super.init(coder: aDecoder) |
|||
} |
|||
} |
@ -1,56 +0,0 @@ |
|||
// |
|||
// WebViewController.swift |
|||
// elpha-ios |
|||
// |
|||
// Created by Dwayne Harris on 9/17/18. |
|||
// Copyright © 2018 Elpha. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
import UIKit |
|||
import WebKit |
|||
|
|||
class WebViewController: UIViewController, WKNavigationDelegate { |
|||
@IBOutlet var mainWebView: WKWebView! |
|||
@IBOutlet var mainProgressView: UIProgressView! |
|||
|
|||
var url: URL? = nil |
|||
|
|||
override func viewDidLoad() { |
|||
super.viewDidLoad() |
|||
|
|||
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white] |
|||
|
|||
mainWebView.navigationDelegate = self |
|||
mainWebView.addObserver(self, forKeyPath: #keyPath(WKWebView.title), options: .new, context: nil) |
|||
mainWebView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil) |
|||
|
|||
if let url = url { |
|||
mainWebView.load(URLRequest(url: url)) |
|||
} |
|||
} |
|||
|
|||
@objc func done() { |
|||
dismiss(animated: true, completion: nil) |
|||
} |
|||
|
|||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { |
|||
if keyPath == #keyPath(WKWebView.title) { |
|||
if let title = mainWebView.title { |
|||
navigationItem.title = title |
|||
} |
|||
} |
|||
|
|||
if keyPath == #keyPath(WKWebView.estimatedProgress) { |
|||
mainProgressView.progress = Float(mainWebView.estimatedProgress) |
|||
} |
|||
} |
|||
|
|||
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { |
|||
mainProgressView.alpha = 1.0 |
|||
} |
|||
|
|||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { |
|||
mainProgressView.alpha = 0.0 |
|||
} |
|||
} |
@ -1,22 +0,0 @@ |
|||
// |
|||
// WebViewHelper.swift |
|||
// elpha-ios |
|||
// |
|||
// Created by Dwayne Harris on 9/17/18. |
|||
// Copyright © 2018 Elpha. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
import UIKit |
|||
|
|||
class WebViewHelper { |
|||
static func getWebViewController(url: URL) -> WebViewController? { |
|||
let storyboard = UIStoryboard(name: "Main", bundle: nil) |
|||
if let webViewController = storyboard.instantiateViewController(withIdentifier: "WebViewController") as? WebViewController { |
|||
webViewController.url = url |
|||
return webViewController |
|||
} |
|||
|
|||
fatalError("Could not instantiate WebViewController") |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue