Giter VIP home page Giter VIP logo

swiftgen's Introduction

SwiftGen

CI Status

This is a suite of tools written in Swift 2 to auto-generate Swift 2 code for various assets of your project:

Installation

Note: The tools are written in Swift 2.0 and need to be compiled with the latest Xcode 7.
The Rakefile will automatically find the copy of Xcode 7.x installed on your Mac (using mdfind) and use it to compile the tools, even if you don't have it set as xcode-select -p.

Compile from source

Clone the repository and use rake to build the tool.

# will install the binary in `/usr/local/bin` and the frameworks in `/usr/local/Frameworks`
$ rake install
# will install the binary in `~/bin` and the frameworks in `~/lib`
$ rake install[~/bin,~/lib]

With this solution you're sure to build and install the latest version from master.

Via Homebrew

You can also install SwiftGen via Homebrew:

$ brew install swiftgen

Usage

The tool is now a unique swiftgen binary command-line with subcommands (like git and pod and commands alike):

  • swiftgen images [OPTIONS] DIR
  • swiftgen strings [OPTIONS] FILE
  • swiftgen storyboards [OPTIONS] DIR
  • swiftgen colors [OPTIONS] FILE

Each subcommand may have its own option and syntax, but here are some common options:

  • --output FILE: set the file where to write the generated code. If omitted, the generated code will be printed on stdout.

You can use --help on swiftgen or one of its subcommand to see the detailed usage.

Playground

The SwiftGen.playground available in this repository will allow you to play with the code that the tools typically generates, and see some examples of how you can take advantage of it.

This allows you to have a quick look at how typical code generated by SwiftGen looks like, and how you will then use the generated enums in your code.

Note: The playground is in the Xcode 7 format, and uses its new concept of "Playground pages" to regroup multiple playground pages in a single Playground.


UIImage

swiftgen images /dir/to/search/for/imageset/assets

This tool will generate an enum Asset in an extension of UIImage, with one case per image asset in your assets catalog, so that you can use them as constants.

Generated code

The generated code will look like this:

extension UIImage {
    enum Asset : String {
        case GreenApple = "Green-Apple"
        case RedApple = "Red-Apple"
        case Banana = "Banana"
        case BigPear = "Big_Pear"
        case StopButtonEnabled = "stop.button.enabled"
        
        var image: UIImage {
            return UIImage(named: self.rawValue)!
        }
    }
    
    convenience init!(asset: Asset) {
        self.init(named: asset.rawValue)
    }
}

Usage Example

let image1 = UIImage.Asset.Apple.image
let image2 = UIImage(asset: .Banana)

This way, no need to enter the "Banana" string in your code and risk any typo.

Benefits & Limitations

There are multiple benefits in using this:

  • Avoid any typo you could have when using a String
  • Free auto-completion
  • Avoid the risk to use an non-existing asset name
  • All this will be ensured by the compiler.

Note that this script only generate extensions and code compatible with UIKit and UIImage. It would be nice to have an option to generate OSX code in the future.

Localizable.strings

swiftgen strings /path/to/Localizable.strings

This tool generate a Swift enum L10n that will map all your Localizable.strings keys to an enum case. Additionaly, if it detects placeholders like %@,%d,%f, it will add associated values to that case.

Generated code

Given the following Localizable.strings file:

"alert_title" = "Title of the alert";
"alert_message" = "Some alert body there";
"greetings" = "Hello, my name is %@ and I'm %d";
"apples.count" = "You have %d apples";
"bananas.owner" = "Those %d bananas belong to %@.";

The generated code will contain this:

enum L10n {
	case AlertTitle
	case AlertMessage
	case Greetings(String, Int)
	case ApplesCount(Int)
	case BananasOwner(Int, String)
}

extension L10n : CustomStringConvertible {
	var description : String { return self.string }

	var string : String {
		/* Implementation Details */
	}
	...
}

func tr(key: L10n) -> String {
	return key.string
}

Usage Example

Once the code has been generated by the script, you can use it this way in your Swift code:

let title = L10n.AlertTitle.string
// -> "Title of the Alert"

// Alternative syntax, shorter
let msg = tr(.AlertMessage)
// -> "Body of the Alert"

// Strings with parameters
let nbApples = tr(.ApplesCount(5))
// -> "You have 5 apples"

// More parameters of various types!
let ban = tr(.BananasOwner(2, "John"))
// -> "Those 2 bananas belong to John."

UIStoryboard

swiftgen storyboards /dir/to/search/for/storyboards

This tool generate an enum for each of your UIStoryboard, with one case per storyboard scene.

Generated code

The generated code will look like this:

protocol StoryboardScene : RawRepresentable {
    static var storyboardName : String { get }
    static func storyboard() -> UIStoryboard
    static func initialViewController() -> UIViewController
    func viewController() -> UIViewController
    static func viewController(identifier: Self) -> UIViewController
}

extension StoryboardScene where Self.RawValue == String {
    /* Implementation details */
}

extension UIStoryboard {
    struct Scene {
        enum Wizard : String, StoryboardScene {
            static let storyboardName = "Wizard"

            case CreateAccount = "CreateAccount"
            static func createAccountViewController() -> CreateAccViewController {
                return Wizard.CreateAccount.viewController() as! CreateAccViewController
            }

            case ValidatePassword = "Validate_Password"
            static func validatePasswordViewController() -> UIViewController {
                return Wizard.ValidatePassword.viewController()
            }
        }
        enum Message : String, StoryboardScene {
            static let storyboardName = "Message"

            case Composer = "Composer"
            static func composerViewController() -> UIViewController {
                return Message.Composer.viewController()
            }

            case URLChooser = "URLChooser"
            static func urlChooserViewController() -> XXPickerViewController {
                return Message.URLChooser.viewController() as! XXPickerViewController
            }
        }
    }

    struct Segue {
        enum Message : String {
            case Custom = "Custom"
            case Back = "Back"
            case NonCustom = "NonCustom"
        }
    }
}

Usage Example

// Initial VC
let initialVC = UIStoryboard.Scene.Wizard.initialViewController()
// Generic ViewController constructor, returns a UIViewController instance
let validateVC = UIStoryboard.Scene.Wizard.ValidatePassword.viewController()
// Dedicated type var that returns the right type of VC (CreateAccViewController here)
let createVC = UIStoryboard.Scene.Wizard.createAccountViewController()

override func prepareForSegue(_ segue: UIStoryboardSegue, sender sender: AnyObject?) {
  switch UIStoryboard.Segue.Message(rawValue: segue.identifier)! {
  case .Custom:
    // Prepare for your custom segue transition
  case .Back:
    // Prepare for your custom segue transition
  case .NonCustom:
    // Prepare for your custom segue transition
  }
}

UIColor

swiftgen colors /path/to/colors-file.txt

This tool will generate a enum Name in an extension of UIColor, with one case per color listed in the text file passed as argument.

The text file is expected to have one line per color to register, each line being composed by the Name to give to the color, followed by ":", followed by the Hex representation of the color (like rrggbb or rrggbbaa, optionally prefixed by # or 0x). Whitespaces are ignored.

Generated code

Given the following colors.txt file:

Cyan         : 0xff66ccff
ArticleTitle : #33fe66
ArticleBody  : 339666
Translucent  : ffffffcc

The generated code will look like this:

extension UIColor {
    /* Private Implementation details */
    ...
}

extension UIColor {
    enum Name : UInt32 {
        case Translucent = 0xffffffcc
        case ArticleBody = 0x339666ff
        case Cyan = 0xff66ccff
        case ArticleTitle = 0x33fe66ff
    }

    convenience init(named name: Name) {
        self.init(rgbaValue: name.rawValue)
    }
}

Usage Example

UIColor(named: .ArticleTitle)
UIColor(named: .ArticleBody)
UIColor(named: .Translucent)

This way, no need to enter the color red, green, blue, alpha values each time and create ugly constants in the global namespace for them.


Licence

This code is under the MIT Licence. See LICENSE file in this repository.

Any ideas and contributions welcome!

swiftgen's People

Contributors

alisoftware avatar esttorhe avatar igor-palaguta avatar zeveisenberg avatar

Watchers

James Cloos avatar Sourabh Sharma avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.