// // Data.swift // Haneke // // Created by Hermes Pique on 9/19/14. // Copyright (c) 2014 Haneke. All rights reserved. // import UIKit // See: http://stackoverflow.com/questions/25922152/not-identical-to-self public protocol DataConvertible { associatedtype Result static func convertFromData(_ data:Data) -> Result? } public protocol DataRepresentable { func asData() -> Data! } private let imageSync = NSLock() extension UIImage : DataConvertible, DataRepresentable { public typealias Result = UIImage // HACK: UIImage data initializer is no longer thread safe. See: https://github.com/AFNetworking/AFNetworking/issues/2572#issuecomment-115854482 static func safeImageWithData(_ data:Data) -> Result? { imageSync.lock() let image = UIImage(data:data, scale: scale) imageSync.unlock() return image } public class func convertFromData(_ data: Data) -> Result? { let image = UIImage.safeImageWithData(data) return image } public func asData() -> Data! { return self.hnk_data() as Data? } fileprivate static let scale = UIScreen.main.scale } extension String : DataConvertible, DataRepresentable { public typealias Result = String public static func convertFromData(_ data: Data) -> Result? { let string = NSString(data: data, encoding: String.Encoding.utf8.rawValue) return string as Result? } public func asData() -> Data! { return self.data(using: String.Encoding.utf8) } } extension Data : DataConvertible, DataRepresentable { public typealias Result = Data public static func convertFromData(_ data: Data) -> Result? { return data } public func asData() -> Data! { return self } } public enum JSONV : DataConvertible, DataRepresentable { public typealias Result = JSONV case Dictionary([String:AnyObject]) case Array([AnyObject]) public static func convertFromData(_ data: Data) -> Result? { do { let object : Any = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions()) switch (object) { case let dictionary as [String:AnyObject]: return JSONV.Dictionary(dictionary) case let array as [AnyObject]: return JSONV.Array(array) default: return nil } } catch { Log.error(message: "Invalid JSON data", error: error) return nil } } public func asData() -> Data! { switch (self) { case .Dictionary(let dictionary): return try? JSONSerialization.data(withJSONObject: dictionary, options: JSONSerialization.WritingOptions()) case .Array(let array): return try? JSONSerialization.data(withJSONObject: array, options: JSONSerialization.WritingOptions()) } } public var array : [AnyObject]! { switch (self) { case .Dictionary(_): return nil case .Array(let array): return array } } public var dictionary : [String:AnyObject]! { switch (self) { case .Dictionary(let dictionary): return dictionary case .Array(_): return nil } } }