Skip to content

Commit

Permalink
Merge swift2 branch
Browse files Browse the repository at this point in the history
  • Loading branch information
jlandon committed Sep 17, 2015
2 parents 14e3ac5 + 93031be commit 1978ec9
Show file tree
Hide file tree
Showing 18 changed files with 324 additions and 236 deletions.
8 changes: 2 additions & 6 deletions .travis.yml
@@ -1,8 +1,4 @@
language: objective-c
osx_image: xcode6.4
# blacklist
branches:
except:
- swift2
osx_image: xcode7
script:
- xcodebuild -project ModelRocket.xcodeproj -scheme ModelRocket -sdk iphonesimulator8.4 test
- xcodebuild -project ModelRocket.xcodeproj -scheme ModelRocket -sdk iphonesimulator9.0 test
6 changes: 3 additions & 3 deletions ModelRocket.playground/Contents.swift
Expand Up @@ -11,7 +11,7 @@ unwrapped safely, since the object will be created iff all properties where
*/

class Vehicle: ModelRocket {
class Vehicle: Model {
let model = Property<String>(key: "model")
let year = Property<Int>(key: "year")
let color = Property<UIColor>(key: "color")
Expand All @@ -37,10 +37,10 @@ if let vehicle = Vehicle(strictJSON: json) {
vehicle.year[]

for color in vehicle.availableColors {
println("Color: \(color)")
print("Color: \(color)")
}

for (key, value) in vehicle.availableTrims {
println("Trim \(key) : \(value)")
print("Trim \(key) : \(value)")
}
}
2 changes: 1 addition & 1 deletion ModelRocket.playground/contents.xcplayground
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<playground version='5.0' target-platform='ios' requires-full-environment='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>
2 changes: 1 addition & 1 deletion ModelRocket.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "ModelRocket"
s.version = "1.0"
s.version = "1.1"
s.license = "MIT"
s.summary = "An iOS framework for creating JSON-based models. Written in Swift."
s.homepage = "https://github.com/ovenbits/ModelRocket"
Expand Down
17 changes: 12 additions & 5 deletions ModelRocket.xcodeproj/project.pbxproj
Expand Up @@ -18,7 +18,7 @@
81F54F681A82D5D9005C8275 /* PropertyDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F54F671A82D5D9005C8275 /* PropertyDescription.swift */; };
81F54F6B1A82D5E1005C8275 /* JSONTransformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F54F6A1A82D5E1005C8275 /* JSONTransformable.swift */; };
81F54F6E1A82D5ED005C8275 /* Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F54F6D1A82D5ED005C8275 /* Property.swift */; };
81F54F711A82D5F5005C8275 /* ModelRocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F54F701A82D5F5005C8275 /* ModelRocket.swift */; };
81F54F711A82D5F5005C8275 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F54F701A82D5F5005C8275 /* Model.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -46,7 +46,7 @@
81F54F671A82D5D9005C8275 /* PropertyDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PropertyDescription.swift; path = ../ModelRocket/PropertyDescription.swift; sourceTree = "<group>"; };
81F54F6A1A82D5E1005C8275 /* JSONTransformable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONTransformable.swift; path = ../ModelRocket/JSONTransformable.swift; sourceTree = "<group>"; };
81F54F6D1A82D5ED005C8275 /* Property.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Property.swift; path = ../ModelRocket/Property.swift; sourceTree = "<group>"; };
81F54F701A82D5F5005C8275 /* ModelRocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ModelRocket.swift; path = ../ModelRocket/ModelRocket.swift; sourceTree = "<group>"; };
81F54F701A82D5F5005C8275 /* Model.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -95,7 +95,7 @@
81F54F6D1A82D5ED005C8275 /* Property.swift */,
810653281A847016004CA201 /* PropertyArray.swift */,
81629FCD1A95780100C2C42D /* PropertyDictionary.swift */,
81F54F701A82D5F5005C8275 /* ModelRocket.swift */,
81F54F701A82D5F5005C8275 /* Model.swift */,
81BECF191B8BBBF5000F08E9 /* JSON.swift */,
8143C8E41A82BA480077DE22 /* Supporting Files */,
);
Expand Down Expand Up @@ -185,7 +185,9 @@
8143C8D81A82BA480077DE22 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
LastSwiftMigration = 0700;
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = "Oven Bits";
TargetAttributes = {
8143C8E01A82BA480077DE22 = {
Expand Down Expand Up @@ -240,7 +242,7 @@
files = (
810653291A847016004CA201 /* PropertyArray.swift in Sources */,
81BECF1A1B8BBBF5000F08E9 /* JSON.swift in Sources */,
81F54F711A82D5F5005C8275 /* ModelRocket.swift in Sources */,
81F54F711A82D5F5005C8275 /* Model.swift in Sources */,
81629FCE1A95780100C2C42D /* PropertyDictionary.swift in Sources */,
81F54F6B1A82D5E1005C8275 /* JSONTransformable.swift in Sources */,
81F54F6E1A82D5ED005C8275 /* Property.swift in Sources */,
Expand Down Expand Up @@ -289,6 +291,7 @@
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
Expand Down Expand Up @@ -367,6 +370,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.ovenbits.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = ModelRocket;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
Expand All @@ -387,6 +391,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.ovenbits.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = ModelRocket;
SKIP_INSTALL = YES;
};
Expand All @@ -405,6 +410,7 @@
);
INFOPLIST_FILE = ModelRocketTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.ovenbits.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = ModelRocketTests;
};
name = Debug;
Expand All @@ -418,6 +424,7 @@
);
INFOPLIST_FILE = ModelRocketTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.ovenbits.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = ModelRocketTests;
};
name = Release;
Expand Down
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0610"
LastUpgradeVersion = "0700"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down Expand Up @@ -37,10 +37,11 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
Expand All @@ -62,15 +63,18 @@
ReferencedContainer = "container:ModelRocket.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
Expand All @@ -85,10 +89,10 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
Expand Down
4 changes: 2 additions & 2 deletions ModelRocket/Info.plist
Expand Up @@ -7,15 +7,15 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.ovenbits.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>1.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
64 changes: 35 additions & 29 deletions ModelRocket/JSON.swift
Expand Up @@ -35,7 +35,7 @@ public struct JSON {
}

public init(data: NSData?) {
if let data = data, let object: AnyObject = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: nil) {
if let data = data, let object: AnyObject = try? NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) {
self.init(object)
}
else {
Expand Down Expand Up @@ -69,17 +69,21 @@ public struct JSON {
return JSON()
}
}

public var isNil: Bool {
return (object == nil)
}
}

// MARK: - Printable
// MARK: - CustomStringConvertible

extension JSON: Printable {
extension JSON: CustomStringConvertible {
public var description: String {
if let object: AnyObject = object {
switch object {
case is String, is NSNumber, is Float, is Double, is Int, is UInt, is Bool: return "\(object)"
case is [AnyObject], is [String : AnyObject]:
if let data = NSJSONSerialization.dataWithJSONObject(object, options: .PrettyPrinted, error: nil) {
if let data = try? NSJSONSerialization.dataWithJSONObject(object, options: .PrettyPrinted) {
return NSString(data: data, encoding: NSUTF8StringEncoding) as? String ?? ""
}
default: return ""
Expand All @@ -90,9 +94,9 @@ extension JSON: Printable {
}
}

// MARK: - DebugPrintable
// MARK: - CustomDebugStringConvertible

extension JSON: DebugPrintable {
extension JSON: CustomDebugStringConvertible {
public var debugDescription: String {
return description
}
Expand Down Expand Up @@ -265,7 +269,7 @@ extension JSON {
extension JSON {
public var dictionary: [String : JSON]? {
if let dictionary = object as? [String : AnyObject] {
return Dictionary(map(dictionary) { ($0, JSON($1)) })
return Dictionary(dictionary.map { ($0, JSON($1)) })
}
return nil
}
Expand All @@ -286,27 +290,29 @@ extension Dictionary {
extension JSON: Equatable {}

public func ==(lhs: JSON, rhs: JSON) -> Bool {
if let lhsObject: AnyObject = lhs.object, rhsObject: AnyObject = rhs.object {
switch (lhsObject, rhsObject) {
case (let left as String, let right as String):
return left == right
case (let left as Double, let right as Double):
return left == right
case (let left as Float, let right as Float):
return left == right
case (let left as Int, let right as Int):
return left == right
case (let left as UInt, let right as UInt):
return left == right
case (let left as Bool, let right as Bool):
return left == right
case (let left as [AnyObject], let right as [AnyObject]):
return left.map { JSON($0) } == right.map { JSON ($0) }
case (let left as [String : AnyObject], let right as [String : AnyObject]):
return Dictionary(map(left) { ($0, JSON($1)) }) == Dictionary(map(right) { ($0, JSON($1)) })
default: return false
}
guard let lhsObject: AnyObject = lhs.object, rhsObject: AnyObject = rhs.object else { return false }

switch (lhsObject, rhsObject) {
case (let left as String, let right as String):
return left == right
case (let left as Double, let right as Double):
return left == right
case (let left as Float, let right as Float):
return left == right
case (let left as Int, let right as Int):
return left == right
case (let left as UInt, let right as UInt):
return left == right
case (let left as Bool, let right as Bool):
return left == right
case (let left as NSURL, let right as NSURL):
return left == right
case (let left as NSNumber, let right as NSNumber):
return left == right
case (let left as [AnyObject], let right as [AnyObject]):
return left.map { JSON($0) } == right.map { JSON ($0) }
case (let left as [String : AnyObject], let right as [String : AnyObject]):
return Dictionary(left.map { ($0, JSON($1)) }) == Dictionary(right.map { ($0, JSON($1)) })
default: return false
}

return false
}
33 changes: 32 additions & 1 deletion ModelRocket/JSONTransformable.swift
Expand Up @@ -33,6 +33,37 @@ public protocol JSONTransformable {
func toJSON() -> AnyObject
}

// MARK: Default implementation for Model subclasses

extension JSONTransformable where Self: Model {
public static func fromJSON(json: JSON) -> Self? {
return Self(strictJSON: json)
}
public func toJSON() -> AnyObject {
return json().dictionary
}
}

// MARK: Default implementation for RawRepresentable types

extension JSONTransformable where Self: RawRepresentable, Self.RawValue == String {
public static func fromJSON(json: JSON) -> Self? {
return Self(rawValue: json.stringValue)
}
public func toJSON() -> AnyObject {
return rawValue
}
}

extension JSONTransformable where Self: RawRepresentable, Self.RawValue == Int {
public static func fromJSON(json: JSON) -> Self? {
return Self(rawValue: json.intValue)
}
public func toJSON() -> AnyObject {
return rawValue
}
}

// MARK: String

extension String: JSONTransformable {
Expand Down Expand Up @@ -117,7 +148,7 @@ extension NSURL: JSONTransformable {
return json.URL
}
public func toJSON() -> AnyObject {
return absoluteString ?? ""
return absoluteString
}
}

Expand Down

0 comments on commit 1978ec9

Please sign in to comment.