| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352 |
- // 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://tools.ietf.org/html/rfc7231#section-4.3
- */
- 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())
- }
- }
-
- /**
- 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 `false`.
- 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 protocol JSONSubscriptType {}
- extension Int: JSONSubscriptType {}
- extension String: JSONSubscriptType {}
- 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 {
- if sub is String {
- return self[key:sub as! String]
- } else {
- return self[index:sub as! Int]
- }
- }
- set {
- if sub is String {
- self[key:sub as! String] = newValue
- } else {
- self[index:sub as! Int] = 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 newValue != nil {
- 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 newValue != nil {
- 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).description
- 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
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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 newValue != nil {
- 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
- }
- }
- }
- }
- public 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
- }
- }
- public func !=(lhs: NSNumber, rhs: NSNumber) -> Bool {
- return !(lhs == rhs)
- }
- public 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
- }
- }
- public 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
- }
- }
- public 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
- }
- }
- public 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
- }
- }
|