Skip to content

Instantly share code, notes, and snippets.

@warren-gavin
Last active September 10, 2017 14:45
Show Gist options
  • Save warren-gavin/0d1c04db999ab68e7e72b17d573f1059 to your computer and use it in GitHub Desktop.
Save warren-gavin/0d1c04db999ab68e7e72b17d573f1059 to your computer and use it in GitHub Desktop.
fileprivate let _sharedInstance: ContactInfo = ContactInfo()
enum JSONParsingError: Error {
case convertError
case parseError
}
class ContactInfo: NSObject {
fileprivate let server = "http://thingywotsit.com"
class var shared: ContactInfo {
return _sharedInstance
}
private func convertJSON(data:Data) throws -> [[String: Any]] {
guard let jsonDict = try JSONSerialization.jsonObject(with: data) as? [[String: Any]] else {
throw JSONParsingError.convertError
}
return jsonDict
}
private func parseJSON(JSON array: [[String:Any]]) throws -> [Contact]{
var contactList: [Contact] = [Contact]()
for each in array {
do {
let contact = try Contact(object: each)
contactList.append(contact)
} catch {
throw JSONParsingError.parseError
}
}
return contactList
}
func requestContactInfo(completed: @escaping ( contactArray: [Contact]?,error: Error?)->()) {
guard let url = URL(string: "\(server)/users") else {
return
}
let session = URLSession.shared
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
completed(nil, error)
} else if let data = data, let response = response as? HTTPURLResponse, response.statusCode == 200 {
do {
let array = try self.convertJSON(data: data)
let result = try self.parseJSON(JSON: array)
completed(result, nil)
} catch JSONParsingError.convertError {
completed(nil, JSONParsingError.convertError)
} catch let error {
completed(nil, error)
}
} else {
}
}
task.resume()
}
}
typealias JSONFormat = [String: Any]
protocol JSONConstructible {
init?(_ json: JSONFormat)
}
struct Contact: JSONConstructible {
init?(_ json: JSONFormat) {
// Contact stuff goes here...
}
}
extension URL {
private static let baseURL = "http://thingywotsit.com"
static let contacts = URL(string: "(URL.baseURL)/users")!
}
extension Data {
func convertJSON() throws -> [JSONFormat] {
guard let serializedJson = try JSONSerialization.jsonObject(with: self) as? [JSONFormat] else {
throw JSONParsingError.convertError
}
return serializedJson
}
}
extension Array where Element == JSONFormat {
func parseJSON<T: JSONConstructible>() -> [T] {
return flatMap(T.init)
}
}
struct JSONDownloader {
static func download<T: JSONConstructible>(url: URL, completion: @escaping (Result<[T]>) -> Void) {
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard
let data = data,
let response = response as? HTTPURLResponse,
response.statusCode == 200
else {
completion(.failure(error))
return
}
do {
let jsonArray = try data.convertJSON()
let types: [T] = jsonArray.parseJSON()
completion(.success(types))
}
catch let error {
completion(.failure(error))
}
}.resume()
}
}
// To test:
// JSONDownloader.download(url: .contacts) { (result: Result<[Contact]>) in
// ...
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment