Skip to content

Instantly share code, notes, and snippets.

@fatihyildizhan
Created January 3, 2016 21:46
Show Gist options
  • Save fatihyildizhan/450822246e8deb14099c to your computer and use it in GitHub Desktop.
Save fatihyildizhan/450822246e8deb14099c to your computer and use it in GitHub Desktop.
Swifty JSON manual using
// SwiftyJSON.swift
//
// Copyright (c) 2014 Ruoyu Fu, Pinglin Tang
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
// MARK: - Error
///Error domain
public let ErrorDomain: String = "SwiftyJSONErrorDomain"
///Error code
public let ErrorUnsupportedType: Int = 999
public let ErrorIndexOutOfBounds: Int = 900
public let ErrorWrongType: Int = 901
public let ErrorNotExist: Int = 500
public let ErrorInvalidJSON: Int = 490
// MARK: - JSON Type
/**
JSON's type definitions.
See http://www.json.org
*/
public enum Type :Int{
case Number
case String
case Bool
case Array
case Dictionary
case Null
case Unknown
}
// MARK: - JSON Base
public struct JSON {
/**
Creates a JSON using the data.
- parameter data: The NSData used to convert to json.Top level object in data is an NSArray or NSDictionary
- parameter opt: The JSON serialization reading options. `.AllowFragments` by default.
- parameter error: error The NSErrorPointer used to return the error. `nil` by default.
- returns: The created JSON
*/
public init(data:NSData, options opt: NSJSONReadingOptions = .AllowFragments, error: NSErrorPointer = nil) {
do {
let object: AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: opt)
self.init(object)
} catch let aError as NSError {
if error != nil {
error.memory = aError
}
self.init(NSNull())
}
}
/**
Create a JSON from JSON string
- parameter string: Normal json string like '{"a":"b"}'
- returns: The created JSON
*/
public static func parse(string:String) -> JSON {
return string.dataUsingEncoding(NSUTF8StringEncoding)
.flatMap({JSON(data: $0)}) ?? JSON(NSNull())
}
/**
Creates a JSON using the object.
- parameter object: The object must have the following properties: All objects are NSString/String, NSNumber/Int/Float/Double/Bool, NSArray/Array, NSDictionary/Dictionary, or NSNull; All dictionary keys are NSStrings/String; NSNumbers are not NaN or infinity.
- returns: The created JSON
*/
public init(_ object: AnyObject) {
self.object = object
}
/**
Creates a JSON from a [JSON]
- parameter jsonArray: A Swift array of JSON objects
- returns: The created JSON
*/
public init(_ jsonArray:[JSON]) {
self.init(jsonArray.map { $0.object })
}
/**
Creates a JSON from a [String: JSON]
- parameter jsonDictionary: A Swift dictionary of JSON objects
- returns: The created JSON
*/
public init(_ jsonDictionary:[String: JSON]) {
var dictionary = [String: AnyObject]()
for (key, json) in jsonDictionary {
dictionary[key] = json.object
}
self.init(dictionary)
}
/// Private object
private var rawArray: [AnyObject] = []
private var rawDictionary: [String : AnyObject] = [:]
private var rawString: String = ""
private var rawNumber: NSNumber = 0
private var rawNull: NSNull = NSNull()
/// Private type
private var _type: Type = .Null
/// prviate error
private var _error: NSError? = nil
/// Object in JSON
public var object: AnyObject {
get {
switch self.type {
case .Array:
return self.rawArray
case .Dictionary:
return self.rawDictionary
case .String:
return self.rawString
case .Number:
return self.rawNumber
case .Bool:
return self.rawNumber
default:
return self.rawNull
}
}
set {
_error = nil
switch newValue {
case let number as NSNumber:
if number.isBool {
_type = .Bool
} else {
_type = .Number
}
self.rawNumber = number
case let string as String:
_type = .String
self.rawString = string
case _ as NSNull:
_type = .Null
case let array as [AnyObject]:
_type = .Array
self.rawArray = array
case let dictionary as [String : AnyObject]:
_type = .Dictionary
self.rawDictionary = dictionary
default:
_type = .Unknown
_error = NSError(domain: ErrorDomain, code: ErrorUnsupportedType, userInfo: [NSLocalizedDescriptionKey: "It is a unsupported type"])
}
}
}
/// json type
public var type: Type { get { return _type } }
/// Error in JSON
public var error: NSError? { get { return self._error } }
/// The static null json
@available(*, unavailable, renamed="null")
public static var nullJSON: JSON { get { return null } }
public static var null: JSON { get { return JSON(NSNull()) } }
}
// MARK: - CollectionType, SequenceType, Indexable
extension JSON : Swift.CollectionType, Swift.SequenceType, Swift.Indexable {
public typealias Generator = JSONGenerator
public typealias Index = JSONIndex
public var startIndex: JSON.Index {
switch self.type {
case .Array:
return JSONIndex(arrayIndex: self.rawArray.startIndex)
case .Dictionary:
return JSONIndex(dictionaryIndex: self.rawDictionary.startIndex)
default:
return JSONIndex()
}
}
public var endIndex: JSON.Index {
switch self.type {
case .Array:
return JSONIndex(arrayIndex: self.rawArray.endIndex)
case .Dictionary:
return JSONIndex(dictionaryIndex: self.rawDictionary.endIndex)
default:
return JSONIndex()
}
}
public subscript (position: JSON.Index) -> JSON.Generator.Element {
switch self.type {
case .Array:
return (String(position.arrayIndex), JSON(self.rawArray[position.arrayIndex!]))
case .Dictionary:
let (key, value) = self.rawDictionary[position.dictionaryIndex!]
return (key, JSON(value))
default:
return ("", JSON.null)
}
}
/// If `type` is `.Array` or `.Dictionary`, return `array.empty` or `dictonary.empty` otherwise return `true`.
public var isEmpty: Bool {
get {
switch self.type {
case .Array:
return self.rawArray.isEmpty
case .Dictionary:
return self.rawDictionary.isEmpty
default:
return true
}
}
}
/// If `type` is `.Array` or `.Dictionary`, return `array.count` or `dictonary.count` otherwise return `0`.
public var count: Int {
switch self.type {
case .Array:
return self.rawArray.count
case .Dictionary:
return self.rawDictionary.count
default:
return 0
}
}
public func underestimateCount() -> Int {
switch self.type {
case .Array:
return self.rawArray.underestimateCount()
case .Dictionary:
return self.rawDictionary.underestimateCount()
default:
return 0
}
}
/**
If `type` is `.Array` or `.Dictionary`, return a generator over the elements like `Array` or `Dictionary`, otherwise return a generator over empty.
- returns: Return a *generator* over the elements of JSON.
*/
public func generate() -> JSON.Generator {
return JSON.Generator(self)
}
}
public struct JSONIndex: ForwardIndexType, _Incrementable, Equatable, Comparable {
let arrayIndex: Int?
let dictionaryIndex: DictionaryIndex<String, AnyObject>?
let type: Type
init(){
self.arrayIndex = nil
self.dictionaryIndex = nil
self.type = .Unknown
}
init(arrayIndex: Int) {
self.arrayIndex = arrayIndex
self.dictionaryIndex = nil
self.type = .Array
}
init(dictionaryIndex: DictionaryIndex<String, AnyObject>) {
self.arrayIndex = nil
self.dictionaryIndex = dictionaryIndex
self.type = .Dictionary
}
public func successor() -> JSONIndex {
switch self.type {
case .Array:
return JSONIndex(arrayIndex: self.arrayIndex!.successor())
case .Dictionary:
return JSONIndex(dictionaryIndex: self.dictionaryIndex!.successor())
default:
return JSONIndex()
}
}
}
public func ==(lhs: JSONIndex, rhs: JSONIndex) -> Bool {
switch (lhs.type, rhs.type) {
case (.Array, .Array):
return lhs.arrayIndex == rhs.arrayIndex
case (.Dictionary, .Dictionary):
return lhs.dictionaryIndex == rhs.dictionaryIndex
default:
return false
}
}
public func <(lhs: JSONIndex, rhs: JSONIndex) -> Bool {
switch (lhs.type, rhs.type) {
case (.Array, .Array):
return lhs.arrayIndex < rhs.arrayIndex
case (.Dictionary, .Dictionary):
return lhs.dictionaryIndex < rhs.dictionaryIndex
default:
return false
}
}
public func <=(lhs: JSONIndex, rhs: JSONIndex) -> Bool {
switch (lhs.type, rhs.type) {
case (.Array, .Array):
return lhs.arrayIndex <= rhs.arrayIndex
case (.Dictionary, .Dictionary):
return lhs.dictionaryIndex <= rhs.dictionaryIndex
default:
return false
}
}
public func >=(lhs: JSONIndex, rhs: JSONIndex) -> Bool {
switch (lhs.type, rhs.type) {
case (.Array, .Array):
return lhs.arrayIndex >= rhs.arrayIndex
case (.Dictionary, .Dictionary):
return lhs.dictionaryIndex >= rhs.dictionaryIndex
default:
return false
}
}
public func >(lhs: JSONIndex, rhs: JSONIndex) -> Bool {
switch (lhs.type, rhs.type) {
case (.Array, .Array):
return lhs.arrayIndex > rhs.arrayIndex
case (.Dictionary, .Dictionary):
return lhs.dictionaryIndex > rhs.dictionaryIndex
default:
return false
}
}
public struct JSONGenerator : GeneratorType {
public typealias Element = (String, JSON)
private let type: Type
private var dictionayGenerate: DictionaryGenerator<String, AnyObject>?
private var arrayGenerate: IndexingGenerator<[AnyObject]>?
private var arrayIndex: Int = 0
init(_ json: JSON) {
self.type = json.type
if type == .Array {
self.arrayGenerate = json.rawArray.generate()
}else {
self.dictionayGenerate = json.rawDictionary.generate()
}
}
public mutating func next() -> JSONGenerator.Element? {
switch self.type {
case .Array:
if let o = self.arrayGenerate?.next() {
return (String(self.arrayIndex++), JSON(o))
} else {
return nil
}
case .Dictionary:
if let (k, v): (String, AnyObject) = self.dictionayGenerate?.next() {
return (k, JSON(v))
} else {
return nil
}
default:
return nil
}
}
}
// MARK: - Subscript
/**
* To mark both String and Int can be used in subscript.
*/
public enum JSONKey {
case Index(Int)
case Key(String)
}
public protocol JSONSubscriptType {
var jsonKey:JSONKey { get }
}
extension Int: JSONSubscriptType {
public var jsonKey:JSONKey {
return JSONKey.Index(self)
}
}
extension String: JSONSubscriptType {
public var jsonKey:JSONKey {
return JSONKey.Key(self)
}
}
extension JSON {
/// If `type` is `.Array`, return json which's object is `array[index]`, otherwise return null json with error.
private subscript(index index: Int) -> JSON {
get {
if self.type != .Array {
var r = JSON.null
r._error = self._error ?? NSError(domain: ErrorDomain, code: ErrorWrongType, userInfo: [NSLocalizedDescriptionKey: "Array[\(index)] failure, It is not an array"])
return r
} else if index >= 0 && index < self.rawArray.count {
return JSON(self.rawArray[index])
} else {
var r = JSON.null
r._error = NSError(domain: ErrorDomain, code:ErrorIndexOutOfBounds , userInfo: [NSLocalizedDescriptionKey: "Array[\(index)] is out of bounds"])
return r
}
}
set {
if self.type == .Array {
if self.rawArray.count > index && newValue.error == nil {
self.rawArray[index] = newValue.object
}
}
}
}
/// If `type` is `.Dictionary`, return json which's object is `dictionary[key]` , otherwise return null json with error.
private subscript(key key: String) -> JSON {
get {
var r = JSON.null
if self.type == .Dictionary {
if let o = self.rawDictionary[key] {
r = JSON(o)
} else {
r._error = NSError(domain: ErrorDomain, code: ErrorNotExist, userInfo: [NSLocalizedDescriptionKey: "Dictionary[\"\(key)\"] does not exist"])
}
} else {
r._error = self._error ?? NSError(domain: ErrorDomain, code: ErrorWrongType, userInfo: [NSLocalizedDescriptionKey: "Dictionary[\"\(key)\"] failure, It is not an dictionary"])
}
return r
}
set {
if self.type == .Dictionary && newValue.error == nil {
self.rawDictionary[key] = newValue.object
}
}
}
/// If `sub` is `Int`, return `subscript(index:)`; If `sub` is `String`, return `subscript(key:)`.
private subscript(sub sub: JSONSubscriptType) -> JSON {
get {
switch sub.jsonKey {
case .Index(let index): return self[index: index]
case .Key(let key): return self[key: key]
}
}
set {
switch sub.jsonKey {
case .Index(let index): self[index: index] = newValue
case .Key(let key): self[key: key] = newValue
}
}
}
/**
Find a json in the complex data structuresby using the Int/String's array.
- parameter path: The target json's path. Example:
let json = JSON[data]
let path = [9,"list","person","name"]
let name = json[path]
The same as: let name = json[9]["list"]["person"]["name"]
- returns: Return a json found by the path or a null json with error
*/
public subscript(path: [JSONSubscriptType]) -> JSON {
get {
return path.reduce(self) { $0[sub: $1] }
}
set {
switch path.count {
case 0:
return
case 1:
self[sub:path[0]].object = newValue.object
default:
var aPath = path; aPath.removeAtIndex(0)
var nextJSON = self[sub: path[0]]
nextJSON[aPath] = newValue
self[sub: path[0]] = nextJSON
}
}
}
/**
Find a json in the complex data structuresby using the Int/String's array.
- parameter path: The target json's path. Example:
let name = json[9,"list","person","name"]
The same as: let name = json[9]["list"]["person"]["name"]
- returns: Return a json found by the path or a null json with error
*/
public subscript(path: JSONSubscriptType...) -> JSON {
get {
return self[path]
}
set {
self[path] = newValue
}
}
}
// MARK: - LiteralConvertible
extension JSON: Swift.StringLiteralConvertible {
public init(stringLiteral value: StringLiteralType) {
self.init(value)
}
public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
self.init(value)
}
public init(unicodeScalarLiteral value: StringLiteralType) {
self.init(value)
}
}
extension JSON: Swift.IntegerLiteralConvertible {
public init(integerLiteral value: IntegerLiteralType) {
self.init(value)
}
}
extension JSON: Swift.BooleanLiteralConvertible {
public init(booleanLiteral value: BooleanLiteralType) {
self.init(value)
}
}
extension JSON: Swift.FloatLiteralConvertible {
public init(floatLiteral value: FloatLiteralType) {
self.init(value)
}
}
extension JSON: Swift.DictionaryLiteralConvertible {
public init(dictionaryLiteral elements: (String, AnyObject)...) {
self.init(elements.reduce([String : AnyObject]()){(dictionary: [String : AnyObject], element:(String, AnyObject)) -> [String : AnyObject] in
var d = dictionary
d[element.0] = element.1
return d
})
}
}
extension JSON: Swift.ArrayLiteralConvertible {
public init(arrayLiteral elements: AnyObject...) {
self.init(elements)
}
}
extension JSON: Swift.NilLiteralConvertible {
public init(nilLiteral: ()) {
self.init(NSNull())
}
}
// MARK: - Raw
extension JSON: Swift.RawRepresentable {
public init?(rawValue: AnyObject) {
if JSON(rawValue).type == .Unknown {
return nil
} else {
self.init(rawValue)
}
}
public var rawValue: AnyObject {
return self.object
}
public func rawData(options opt: NSJSONWritingOptions = NSJSONWritingOptions(rawValue: 0)) throws -> NSData {
guard NSJSONSerialization.isValidJSONObject(self.object) else {
throw NSError(domain: ErrorDomain, code: ErrorInvalidJSON, userInfo: [NSLocalizedDescriptionKey: "JSON is invalid"])
}
return try NSJSONSerialization.dataWithJSONObject(self.object, options: opt)
}
public func rawString(encoding: UInt = NSUTF8StringEncoding, options opt: NSJSONWritingOptions = .PrettyPrinted) -> String? {
switch self.type {
case .Array, .Dictionary:
do {
let data = try self.rawData(options: opt)
return NSString(data: data, encoding: encoding) as? String
} catch _ {
return nil
}
case .String:
return self.rawString
case .Number:
return self.rawNumber.stringValue
case .Bool:
return self.rawNumber.boolValue.description
case .Null:
return "null"
default:
return nil
}
}
}
// MARK: - Printable, DebugPrintable
extension JSON: Swift.Printable, Swift.DebugPrintable {
public var description: String {
if let string = self.rawString(options:.PrettyPrinted) {
return string
} else {
return "unknown"
}
}
public var debugDescription: String {
return description
}
}
// MARK: - Array
extension JSON {
//Optional [JSON]
public var array: [JSON]? {
get {
if self.type == .Array {
return self.rawArray.map{ JSON($0) }
} else {
return nil
}
}
}
//Non-optional [JSON]
public var arrayValue: [JSON] {
get {
return self.array ?? []
}
}
//Optional [AnyObject]
public var arrayObject: [AnyObject]? {
get {
switch self.type {
case .Array:
return self.rawArray
default:
return nil
}
}
set {
if let array = newValue {
self.object = array
} else {
self.object = NSNull()
}
}
}
}
// MARK: - Dictionary
extension JSON {
//Optional [String : JSON]
public var dictionary: [String : JSON]? {
if self.type == .Dictionary {
return self.rawDictionary.reduce([String : JSON]()) { (dictionary: [String : JSON], element: (String, AnyObject)) -> [String : JSON] in
var d = dictionary
d[element.0] = JSON(element.1)
return d
}
} else {
return nil
}
}
//Non-optional [String : JSON]
public var dictionaryValue: [String : JSON] {
return self.dictionary ?? [:]
}
//Optional [String : AnyObject]
public var dictionaryObject: [String : AnyObject]? {
get {
switch self.type {
case .Dictionary:
return self.rawDictionary
default:
return nil
}
}
set {
if let v = newValue {
self.object = v
} else {
self.object = NSNull()
}
}
}
}
// MARK: - Bool
extension JSON: Swift.BooleanType {
//Optional bool
public var bool: Bool? {
get {
switch self.type {
case .Bool:
return self.rawNumber.boolValue
default:
return nil
}
}
set {
if let newValue = newValue {
self.object = NSNumber(bool: newValue)
} else {
self.object = NSNull()
}
}
}
//Non-optional bool
public var boolValue: Bool {
get {
switch self.type {
case .Bool, .Number, .String:
return self.object.boolValue
default:
return false
}
}
set {
self.object = NSNumber(bool: newValue)
}
}
}
// MARK: - String
extension JSON {
//Optional string
public var string: String? {
get {
switch self.type {
case .String:
return self.object as? String
default:
return nil
}
}
set {
if let newValue = newValue {
self.object = NSString(string:newValue)
} else {
self.object = NSNull()
}
}
}
//Non-optional string
public var stringValue: String {
get {
switch self.type {
case .String:
return self.object as? String ?? ""
case .Number:
return self.object.stringValue
case .Bool:
return (self.object as? Bool).map { String($0) } ?? ""
default:
return ""
}
}
set {
self.object = NSString(string:newValue)
}
}
}
// MARK: - Number
extension JSON {
//Optional number
public var number: NSNumber? {
get {
switch self.type {
case .Number, .Bool:
return self.rawNumber
default:
return nil
}
}
set {
self.object = newValue ?? NSNull()
}
}
//Non-optional number
public var numberValue: NSNumber {
get {
switch self.type {
case .String:
let decimal = NSDecimalNumber(string: self.object as? String)
if decimal == NSDecimalNumber.notANumber() { // indicates parse error
return NSDecimalNumber.zero()
}
return decimal
case .Number, .Bool:
return self.object as? NSNumber ?? NSNumber(int: 0)
default:
return NSNumber(double: 0.0)
}
}
set {
self.object = newValue
}
}
}
//MARK: - Null
extension JSON {
public var null: NSNull? {
get {
switch self.type {
case .Null:
return self.rawNull
default:
return nil
}
}
set {
self.object = NSNull()
}
}
public func isExists() -> Bool{
if let errorValue = error where errorValue.code == ErrorNotExist{
return false
}
return true
}
}
//MARK: - URL
extension JSON {
//Optional URL
public var URL: NSURL? {
get {
switch self.type {
case .String:
if let encodedString_ = self.rawString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) {
return NSURL(string: encodedString_)
} else {
return nil
}
default:
return nil
}
}
set {
self.object = newValue?.absoluteString ?? NSNull()
}
}
}
// MARK: - Int, Double, Float, Int8, Int16, Int32, Int64
extension JSON {
public var double: Double? {
get {
return self.number?.doubleValue
}
set {
if let newValue = newValue {
self.object = NSNumber(double: newValue)
} else {
self.object = NSNull()
}
}
}
public var doubleValue: Double {
get {
return self.numberValue.doubleValue
}
set {
self.object = NSNumber(double: newValue)
}
}
public var float: Float? {
get {
return self.number?.floatValue
}
set {
if let newValue = newValue {
self.object = NSNumber(float: newValue)
} else {
self.object = NSNull()
}
}
}
public var floatValue: Float {
get {
return self.numberValue.floatValue
}
set {
self.object = NSNumber(float: newValue)
}
}
public var int: Int? {
get {
return self.number?.longValue
}
set {
if let newValue = newValue {
self.object = NSNumber(integer: newValue)
} else {
self.object = NSNull()
}
}
}
public var intValue: Int {
get {
return self.numberValue.integerValue
}
set {
self.object = NSNumber(integer: newValue)
}
}
public var uInt: UInt? {
get {
return self.number?.unsignedLongValue
}
set {
if let newValue = newValue {
self.object = NSNumber(unsignedLong: newValue)
} else {
self.object = NSNull()
}
}
}
public var uIntValue: UInt {
get {
return self.numberValue.unsignedLongValue
}
set {
self.object = NSNumber(unsignedLong: newValue)
}
}
public var int8: Int8? {
get {
return self.number?.charValue
}
set {
if let newValue = newValue {
self.object = NSNumber(char: newValue)
} else {
self.object = NSNull()
}
}
}
public var int8Value: Int8 {
get {
return self.numberValue.charValue
}
set {
self.object = NSNumber(char: newValue)
}
}
public var uInt8: UInt8? {
get {
return self.number?.unsignedCharValue
}
set {
if let newValue = newValue {
self.object = NSNumber(unsignedChar: newValue)
} else {
self.object = NSNull()
}
}
}
public var uInt8Value: UInt8 {
get {
return self.numberValue.unsignedCharValue
}
set {
self.object = NSNumber(unsignedChar: newValue)
}
}
public var int16: Int16? {
get {
return self.number?.shortValue
}
set {
if let newValue = newValue {
self.object = NSNumber(short: newValue)
} else {
self.object = NSNull()
}
}
}
public var int16Value: Int16 {
get {
return self.numberValue.shortValue
}
set {
self.object = NSNumber(short: newValue)
}
}
public var uInt16: UInt16? {
get {
return self.number?.unsignedShortValue
}
set {
if let newValue = newValue {
self.object = NSNumber(unsignedShort: newValue)
} else {
self.object = NSNull()
}
}
}
public var uInt16Value: UInt16 {
get {
return self.numberValue.unsignedShortValue
}
set {
self.object = NSNumber(unsignedShort: newValue)
}
}
public var int32: Int32? {
get {
return self.number?.intValue
}
set {
if let newValue = newValue {
self.object = NSNumber(int: newValue)
} else {
self.object = NSNull()
}
}
}
public var int32Value: Int32 {
get {
return self.numberValue.intValue
}
set {
self.object = NSNumber(int: newValue)
}
}
public var uInt32: UInt32? {
get {
return self.number?.unsignedIntValue
}
set {
if let newValue = newValue {
self.object = NSNumber(unsignedInt: newValue)
} else {
self.object = NSNull()
}
}
}
public var uInt32Value: UInt32 {
get {
return self.numberValue.unsignedIntValue
}
set {
self.object = NSNumber(unsignedInt: newValue)
}
}
public var int64: Int64? {
get {
return self.number?.longLongValue
}
set {
if let newValue = newValue {
self.object = NSNumber(longLong: newValue)
} else {
self.object = NSNull()
}
}
}
public var int64Value: Int64 {
get {
return self.numberValue.longLongValue
}
set {
self.object = NSNumber(longLong: newValue)
}
}
public var uInt64: UInt64? {
get {
return self.number?.unsignedLongLongValue
}
set {
if let newValue = newValue {
self.object = NSNumber(unsignedLongLong: newValue)
} else {
self.object = NSNull()
}
}
}
public var uInt64Value: UInt64 {
get {
return self.numberValue.unsignedLongLongValue
}
set {
self.object = NSNumber(unsignedLongLong: newValue)
}
}
}
//MARK: - Comparable
extension JSON : Swift.Comparable {}
public func ==(lhs: JSON, rhs: JSON) -> Bool {
switch (lhs.type, rhs.type) {
case (.Number, .Number):
return lhs.rawNumber == rhs.rawNumber
case (.String, .String):
return lhs.rawString == rhs.rawString
case (.Bool, .Bool):
return lhs.rawNumber.boolValue == rhs.rawNumber.boolValue
case (.Array, .Array):
return lhs.rawArray as NSArray == rhs.rawArray as NSArray
case (.Dictionary, .Dictionary):
return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary
case (.Null, .Null):
return true
default:
return false
}
}
public func <=(lhs: JSON, rhs: JSON) -> Bool {
switch (lhs.type, rhs.type) {
case (.Number, .Number):
return lhs.rawNumber <= rhs.rawNumber
case (.String, .String):
return lhs.rawString <= rhs.rawString
case (.Bool, .Bool):
return lhs.rawNumber.boolValue == rhs.rawNumber.boolValue
case (.Array, .Array):
return lhs.rawArray as NSArray == rhs.rawArray as NSArray
case (.Dictionary, .Dictionary):
return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary
case (.Null, .Null):
return true
default:
return false
}
}
public func >=(lhs: JSON, rhs: JSON) -> Bool {
switch (lhs.type, rhs.type) {
case (.Number, .Number):
return lhs.rawNumber >= rhs.rawNumber
case (.String, .String):
return lhs.rawString >= rhs.rawString
case (.Bool, .Bool):
return lhs.rawNumber.boolValue == rhs.rawNumber.boolValue
case (.Array, .Array):
return lhs.rawArray as NSArray == rhs.rawArray as NSArray
case (.Dictionary, .Dictionary):
return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary
case (.Null, .Null):
return true
default:
return false
}
}
public func >(lhs: JSON, rhs: JSON) -> Bool {
switch (lhs.type, rhs.type) {
case (.Number, .Number):
return lhs.rawNumber > rhs.rawNumber
case (.String, .String):
return lhs.rawString > rhs.rawString
default:
return false
}
}
public func <(lhs: JSON, rhs: JSON) -> Bool {
switch (lhs.type, rhs.type) {
case (.Number, .Number):
return lhs.rawNumber < rhs.rawNumber
case (.String, .String):
return lhs.rawString < rhs.rawString
default:
return false
}
}
private let trueNumber = NSNumber(bool: true)
private let falseNumber = NSNumber(bool: false)
private let trueObjCType = String.fromCString(trueNumber.objCType)
private let falseObjCType = String.fromCString(falseNumber.objCType)
// MARK: - NSNumber: Comparable
extension NSNumber {
var isBool:Bool {
get {
let objCType = String.fromCString(self.objCType)
if (self.compare(trueNumber) == NSComparisonResult.OrderedSame && objCType == trueObjCType)
|| (self.compare(falseNumber) == NSComparisonResult.OrderedSame && objCType == falseObjCType){
return true
} else {
return false
}
}
}
}
func ==(lhs: NSNumber, rhs: NSNumber) -> Bool {
switch (lhs.isBool, rhs.isBool) {
case (false, true):
return false
case (true, false):
return false
default:
return lhs.compare(rhs) == NSComparisonResult.OrderedSame
}
}
func !=(lhs: NSNumber, rhs: NSNumber) -> Bool {
return !(lhs == rhs)
}
func <(lhs: NSNumber, rhs: NSNumber) -> Bool {
switch (lhs.isBool, rhs.isBool) {
case (false, true):
return false
case (true, false):
return false
default:
return lhs.compare(rhs) == NSComparisonResult.OrderedAscending
}
}
func >(lhs: NSNumber, rhs: NSNumber) -> Bool {
switch (lhs.isBool, rhs.isBool) {
case (false, true):
return false
case (true, false):
return false
default:
return lhs.compare(rhs) == NSComparisonResult.OrderedDescending
}
}
func <=(lhs: NSNumber, rhs: NSNumber) -> Bool {
switch (lhs.isBool, rhs.isBool) {
case (false, true):
return false
case (true, false):
return false
default:
return lhs.compare(rhs) != NSComparisonResult.OrderedDescending
}
}
func >=(lhs: NSNumber, rhs: NSNumber) -> Bool {
switch (lhs.isBool, rhs.isBool) {
case (false, true):
return false
case (true, false):
return false
default:
return lhs.compare(rhs) != NSComparisonResult.OrderedAscending
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment