Skip to content

Commit

Permalink
Merge pull request #49 from insanoid/releases/v1.2.0
Browse files Browse the repository at this point in the history
Releases/v1.2.0
  • Loading branch information
Karthikeya Udupa KM authored Dec 4, 2016
2 parents 92384b9 + 7d0fbc0 commit 1ae5a01
Show file tree
Hide file tree
Showing 16 changed files with 603 additions and 373 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
[![Build
Status](https://travis-ci.org/insanoid/SwiftyJSONAccelerator.svg?branch=master)](https://travis-ci.org/insanoid/SwiftyJSONAccelerator) [![codecov](https://codecov.io/gh/insanoid/SwiftyJSONAccelerator/branch/master/graph/badge.svg)](https://codecov.io/gh/insanoid/SwiftyJSONAccelerator)

**Version v1.2.0 Released!**

- Now supports [Marshal](https://github.com/utahiosmac/Marshal)! One of the fastest JSONSerialisation class out there! [(Read more)](https://github.com/bwhiteley/JSONShootout)
- Set `class` as `final`.
- `init` marked as `required` by default for `class`.

**Version v1.1.0 Released!**

- Now generates the correct option `struct` and `class` based on what was selected.
Expand All @@ -18,15 +24,16 @@ Status](https://travis-ci.org/insanoid/SwiftyJSONAccelerator.svg?branch=master)]

## Download/Installing

- Download the repo, install pods and run the project!
- [Download the .app(v1.1.0)](https://github.com/insanoid/SwiftyJSONAccelerator/releases/download/v1.1.0/SwiftyJSONAccelerator.zip).0/SwiftyJSONAccelerator.zip)
- **Option 1:** Download the repo, install pods and run the project!
- **Option 2:** [Download the .app(v1.2.0)](https://github.com/insanoid/SwiftyJSONAccelerator/releases/download/v1.2.0/SwiftyJSONAccelerator.zip)

A swift model generator like the Objective-C [JSONAccelerator](http://nerdery.com/json-accelerator). Formats and generates models for the given JSON and also breaks them into files making it easy to manage and share between several models.

The models that are generated depend on JSON object mapping libraries, currently the model can be generated to depend on any of the below mentioned mapping libraries:

- [SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON)
- [Hearst-DD/ObjectMapper](https://github.com/Hearst-DD/ObjectMapper)
- [Marshal](https://github.com/utahiosmac/Marshal)

Currently, the pattern is very similar to its Objective-C counterpart. It generates classes with following properties.

Expand Down
12 changes: 11 additions & 1 deletion SwiftyJSONAccelerator.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
930462B51D31131800FE61A6 /* PropertyComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 930462B11D310FF200FE61A6 /* PropertyComponent.swift */; };
930462B61D31133B00FE61A6 /* FileGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 930462AC1D3106A400FE61A6 /* FileGenerator.swift */; };
930462B71D31134900FE61A6 /* ModelComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 930462AF1D310F6900FE61A6 /* ModelComponent.swift */; };
9327F2881DF4BCA70002BE40 /* MarshalModelFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9327F2871DF4BCA70002BE40 /* MarshalModelFile.swift */; };
9327F28A1DF4BD540002BE40 /* MarshalTemplate.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9327F2891DF4BD540002BE40 /* MarshalTemplate.txt */; };
9327F2971DF4CF650002BE40 /* MarshalModelFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9327F2871DF4BCA70002BE40 /* MarshalModelFile.swift */; };
9341A14A1BD6E5FE0048CE2C /* ModelGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9341A1491BD6E5FE0048CE2C /* ModelGenerator.swift */; };
9341A14F1BD6E7290048CE2C /* BaseTemplate.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9341A14E1BD6E7290048CE2C /* BaseTemplate.txt */; };
9361FD141BD18558001ED533 /* LineNumberRulerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9361FD131BD18558001ED533 /* LineNumberRulerView.swift */; };
Expand Down Expand Up @@ -79,6 +82,8 @@
930462AC1D3106A400FE61A6 /* FileGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileGenerator.swift; sourceTree = "<group>"; };
930462AF1D310F6900FE61A6 /* ModelComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModelComponent.swift; sourceTree = "<group>"; };
930462B11D310FF200FE61A6 /* PropertyComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PropertyComponent.swift; sourceTree = "<group>"; };
9327F2871DF4BCA70002BE40 /* MarshalModelFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarshalModelFile.swift; sourceTree = "<group>"; };
9327F2891DF4BD540002BE40 /* MarshalTemplate.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MarshalTemplate.txt; sourceTree = "<group>"; };
9341A1491BD6E5FE0048CE2C /* ModelGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModelGenerator.swift; sourceTree = "<group>"; };
9341A14E1BD6E7290048CE2C /* BaseTemplate.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = BaseTemplate.txt; sourceTree = "<group>"; };
9361FD131BD18558001ED533 /* LineNumberRulerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineNumberRulerView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -211,6 +216,7 @@
children = (
93F1593F1CFF96E700175636 /* ObjectMapperModelFile.swift */,
93F1593D1CFF969900175636 /* SwiftyJSONModelFile.swift */,
9327F2871DF4BCA70002BE40 /* MarshalModelFile.swift */,
);
path = "Library-Extensions";
sourceTree = "<group>";
Expand Down Expand Up @@ -291,6 +297,7 @@
children = (
C667011C1BDCAF23009BA254 /* ObjectMapperTemplate.txt */,
C667011A1BDCABCE009BA254 /* SwiftyJSONTemplate.txt */,
9327F2891DF4BD540002BE40 /* MarshalTemplate.txt */,
);
path = "Library-Extension-Templates";
sourceTree = "<group>";
Expand Down Expand Up @@ -369,7 +376,7 @@
93F174371BD0707D007E7DFC /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0810;
ORGANIZATIONNAME = "Karthikeya Udupa K M";
TargetAttributes = {
93F1743E1BD0707D007E7DFC = {
Expand Down Expand Up @@ -414,6 +421,7 @@
C667011D1BDCAF23009BA254 /* ObjectMapperTemplate.txt in Resources */,
9341A14F1BD6E7290048CE2C /* BaseTemplate.txt in Resources */,
93F1744A1BD0707D007E7DFC /* Main.storyboard in Resources */,
9327F28A1DF4BD540002BE40 /* MarshalTemplate.txt in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -549,6 +557,7 @@
9341A14A1BD6E5FE0048CE2C /* ModelGenerator.swift in Sources */,
930462B21D310FF200FE61A6 /* PropertyComponent.swift in Sources */,
93F1593A1CFF853C00175636 /* NameGenerator.swift in Sources */,
9327F2881DF4BCA70002BE40 /* MarshalModelFile.swift in Sources */,
930462AD1D3106A400FE61A6 /* FileGenerator.swift in Sources */,
93F174451BD0707D007E7DFC /* SJEditorViewController.swift in Sources */,
93F1593E1CFF969900175636 /* SwiftyJSONModelFile.swift in Sources */,
Expand Down Expand Up @@ -578,6 +587,7 @@
93D850EF1D00D3070023D573 /* ObjectMapperModelFile.swift in Sources */,
93D850DC1D00D2ED0023D573 /* SJEditorViewController.swift in Sources */,
93D850D81D00D2030023D573 /* ModelGenerator.swift in Sources */,
9327F2971DF4CF650002BE40 /* MarshalModelFile.swift in Sources */,
93D850E91D00D3020023D573 /* String+Helpers.swift in Sources */,
9362F8661BD07DBA0001372E /* JSONHelperTests.swift in Sources */,
93D850DE1D00D2F00023D573 /* SJTextView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 2 additions & 0 deletions SwiftyJSONAccelerator/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ enum ConstructType: String {

- SwiftyJSON: SwiftyJSON - https://github.com/SwiftyJSON/SwiftyJSON
- ObjectMapper: ObjectMapper - https://github.com/Hearst-DD/ObjectMapper
- Marshal: Marshal - https://github.com/utahiosmac/Marshal
*/
enum JSONMappingLibrary: String {
case SwiftyJSON
case ObjectMapper
case Marshal
}

/**
Expand Down
178 changes: 95 additions & 83 deletions SwiftyJSONAccelerator/Generators/FileGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,85 +10,97 @@ import Foundation

struct FileGenerator {

/**
/**
Fetch the template for creating model.swift files.

- parameter filename: Name of the file to be loaded

- returns: String containing the template.
*/
static func loadFileWith(_ filename: String) -> String {
static func loadFileWith(_ filename: String) -> String {

let bundle = Bundle.main
let path = bundle.path(forResource: filename, ofType: "txt")
let bundle = Bundle.main
let path = bundle.path(forResource: filename, ofType: "txt")

do {
let content = try String.init(contentsOfFile: path!)
return content
} catch { }
do {
let content = try String.init(contentsOfFile: path!)
return content
} catch { }

return ""
}

static func generateFileContentWith(_ modelFile: ModelFile, configuration: ModelGenerationConfiguration) -> String {

var content = loadFileWith("BaseTemplate")
content = content.replacingOccurrences(of: "{OBJECT_NAME}", with: modelFile.fileName)
content = content.replacingOccurrences(of: "{DATE}", with: todayDateString())
content = content.replacingOccurrences(of: "{OBJECT_KIND}", with: modelFile.type.rawValue)
content = content.replacingOccurrences(of: "{JSON_PARSER_LIBRARY_BODY}", with: loadFileWith(modelFile.mainBodyFileName()))
if let authorName = configuration.authorName {
content = content.replacingOccurrences(of: "__NAME__", with: authorName)
}
if let companyName = configuration.companyName {
content = content.replacingOccurrences(of: "__MyCompanyName__", with: companyName)
}
content = content.replacingOccurrences(of: "{INCLUDE_HEADER}", with: "\nimport \(modelFile.moduleName())")

var classesExtendFrom: [String] = []
if let extendFrom = modelFile.baseElementName() {
classesExtendFrom = [extendFrom]
}
if configuration.supportNSCoding && configuration.constructType == .ClassType {
classesExtendFrom = classesExtendFrom + ["NSCoding"]
}

if classesExtendFrom.count > 0 {
content = content.replacingOccurrences(of: "{EXTEND_FROM}", with: classesExtendFrom.joined(separator: ", "))
content = content.replacingOccurrences(of: "{EXTENDED_OBJECT_COLON}", with: ": ")
} else {
content = content.replacingOccurrences(of: "{EXTEND_FROM}", with: "")
content = content.replacingOccurrences(of: "{EXTENDED_OBJECT_COLON}", with: "")
return ""
}

let stringConstants = modelFile.component.stringConstants.map({ " " + $0 }).joined(separator: "\n")
let declarations = modelFile.component.declarations.map({ " " + $0 }).joined(separator: "\n")
let initialisers = modelFile.component.initialisers.map({ " " + $0 }).joined(separator: "\n")
let description = modelFile.component.description.map({ " " + $0 }).joined(separator: "\n")

content = content.replacingOccurrences(of: "{STRING_CONSTANT}", with: stringConstants)
content = content.replacingOccurrences(of: "{DECLARATION}", with: declarations)
content = content.replacingOccurrences(of: "{INITALIZER}", with: initialisers)
content = content.replacingOccurrences(of: "{DESCRIPTION}", with: description)

if configuration.constructType == .StructType {
content = content.replacingOccurrences(of: " convenience", with: "")
static func generateFileContentWith(_ modelFile: ModelFile, configuration: ModelGenerationConfiguration) -> String {

var content = loadFileWith("BaseTemplate")
content = content.replacingOccurrences(of: "{OBJECT_NAME}", with: modelFile.fileName)
content = content.replacingOccurrences(of: "{DATE}", with: todayDateString())
content = content.replacingOccurrences(of: "{OBJECT_KIND}", with: modelFile.type.rawValue)
content = content.replacingOccurrences(of: "{JSON_PARSER_LIBRARY_BODY}", with: loadFileWith(modelFile.mainBodyFileName()))

if modelFile.type == .ClassType {
content = content.replacingOccurrences(of: "{REQUIRED}", with: " required ")
} else {
content = content.replacingOccurrences(of: "{REQUIRED}", with: " ")
}
if let authorName = configuration.authorName {
content = content.replacingOccurrences(of: "__NAME__", with: authorName)
}
if let companyName = configuration.companyName {
content = content.replacingOccurrences(of: "__MyCompanyName__", with: companyName)
}
content = content.replacingOccurrences(of: "{INCLUDE_HEADER}", with: "\nimport \(modelFile.moduleName())")

var classesExtendFrom: [String] = []
if let extendFrom = modelFile.baseElementName() {
classesExtendFrom = [extendFrom]
}
if configuration.supportNSCoding && configuration.constructType == .ClassType {
classesExtendFrom = classesExtendFrom + ["NSCoding"]
}

if configuration.isFinalRequired && configuration.constructType == .ClassType {
content = content.replacingOccurrences(of: "{IS_FINAL}", with: " final ")
} else {
content = content.replacingOccurrences(of: "{IS_FINAL}", with: " ")
}

if classesExtendFrom.count > 0 {
content = content.replacingOccurrences(of: "{EXTEND_FROM}", with: classesExtendFrom.joined(separator: ", "))
content = content.replacingOccurrences(of: "{EXTENDED_OBJECT_COLON}", with: ": ")
} else {
content = content.replacingOccurrences(of: "{EXTEND_FROM}", with: "")
content = content.replacingOccurrences(of: "{EXTENDED_OBJECT_COLON}", with: "")
}

let stringConstants = modelFile.component.stringConstants.map({ " " + $0 }).joined(separator: "\n")
let declarations = modelFile.component.declarations.map({ " " + $0 }).joined(separator: "\n")
let initialisers = modelFile.component.initialisers.map({ " " + $0 }).joined(separator: "\n")
let description = modelFile.component.description.map({ " " + $0 }).joined(separator: "\n")

content = content.replacingOccurrences(of: "{STRING_CONSTANT}", with: stringConstants)
content = content.replacingOccurrences(of: "{DECLARATION}", with: declarations)
content = content.replacingOccurrences(of: "{INITIALIZER}", with: initialisers)
content = content.replacingOccurrences(of: "{DESCRIPTION}", with: description)

if configuration.constructType == .StructType {
content = content.replacingOccurrences(of: " convenience", with: "")
}

if configuration.supportNSCoding && configuration.constructType == .ClassType {
content = content.replacingOccurrences(of: "{NSCODING_SUPPORT}", with: loadFileWith("NSCodingTemplate"))
let encoders = modelFile.component.encoders.map({ " " + $0 }).joined(separator: "\n")
let decoders = modelFile.component.decoders.map({ " " + $0 }).joined(separator: "\n")
content = content.replacingOccurrences(of: "{DECODERS}", with: decoders)
content = content.replacingOccurrences(of: "{ENCODERS}", with: encoders)
} else {
content = content.replacingOccurrences(of: "{NSCODING_SUPPORT}", with: "")
}

return content
}

if configuration.supportNSCoding && configuration.constructType == .ClassType {
content = content.replacingOccurrences(of: "{NSCODING_SUPPORT}", with: loadFileWith("NSCodingTemplate"))
let encoders = modelFile.component.encoders.map({ " " + $0 }).joined(separator: "\n")
let decoders = modelFile.component.decoders.map({ " " + $0 }).joined(separator: "\n")
content = content.replacingOccurrences(of: "{DECODERS}", with: decoders)
content = content.replacingOccurrences(of: "{ENCODERS}", with: encoders)
} else {
content = content.replacingOccurrences(of: "{NSCODING_SUPPORT}", with: "")
}

return content
}

/**
/**
Write the given content to a file at the mentioned path.

- parameter name: The name of the file.
Expand All @@ -97,24 +109,24 @@ struct FileGenerator {

- returns: Boolean indicating if the process was successful.
*/
static internal func writeToFileWith(_ name: String, content: String, path: String) -> Bool {
let filename = path.appendingFormat("%@", (name + ".swift"))
do {
try FileManager.default.createDirectory(at: URL.init(fileURLWithPath: path),
withIntermediateDirectories: true,
attributes: nil)
try content.write(toFile: filename, atomically: true, encoding: String.Encoding.utf8)
return true
} catch let error as NSError {
print(error)
return false
static internal func writeToFileWith(_ name: String, content: String, path: String) -> Bool {
let filename = path.appendingFormat("%@", (name + ".swift"))
do {
try FileManager.default.createDirectory(at: URL.init(fileURLWithPath: path),
withIntermediateDirectories: true,
attributes: nil)
try content.write(toFile: filename, atomically: true, encoding: String.Encoding.utf8)
return true
} catch let error as NSError {
print(error)
return false
}
}
}

static fileprivate func todayDateString() -> String {
let formatter = DateFormatter.init()
formatter.dateStyle = .short
return formatter.string(from: Date.init())
}
static fileprivate func todayDateString() -> String {
let formatter = DateFormatter.init()
formatter.dateStyle = .short
return formatter.string(from: Date.init())
}

}
2 changes: 2 additions & 0 deletions SwiftyJSONAccelerator/Generators/ModelGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ public struct ModelGenerator {
return ObjectMapperModelFile()
case .SwiftyJSON:
return SwiftyJSONModelFile()
case .Marshal:
return MarshalModelFile()
}
}

Expand Down
Loading

0 comments on commit 1ae5a01

Please sign in to comment.