Share
Embed
Code Generators In Swift (Part 2)
Talk about code generators in general, and what code generators we can and should use when we're working with ios projects
Paul Taykalo
November 19, 2016
Transcript
79 slides
-
Code Generators in Swift by Paul Taykalo, Stanfy Code Generators
in Swift, #Cocoaheads, Minsk 1 -
Code generation or Automatic Programming In computer science, the term
automatic programming identifies a type of computer programming in which some mechanism generates a computer program to allow human programmers to write the code at a higher abstraction level — Wikipedia Code Generators in Swift, #Cocoaheads, Minsk 3 -
When should we write one? ✅ Structure is well defined
Code Generators in Swift, #Cocoaheads, Minsk 14 -
When should we write one? ✅ Structure is well defined
✅ Number of special cases is low ✅ Uniform structure Code Generators in Swift, #Cocoaheads, Minsk 15 -
When should we write one? ✅ Structure is well defined
✅ Number of special cases is low ✅ Uniform structure ✅ One Layer of Abstraction Code Generators in Swift, #Cocoaheads, Minsk 16 -
When should we write one? ✅ Structure is well defined
✅ Number of special cases is low ✅ Uniform structure ✅ One Layer of Abstraction ✅ It's time efficient Code Generators in Swift, #Cocoaheads, Minsk 17 -
Flow time is limited. Simple operations should take small amount
of time Code Generators in Swift, #Cocoaheads, Minsk 22 -
But before that What so special in code generators for
Swift? Code Generators in Swift, #Cocoaheads, Minsk 28 -
What so special in code generators for Swift? • No
Runtime • Static Typing • No simple way to get types in runtime* • Hard to get metainformation at runtime* Code Generators in Swift, #Cocoaheads, Minsk 29 -
Swagger • Source Language: DSL in YAML / JSON •
Written In: Java • Generates: Everything http://swagger.io/ Code Generators in Swift, #Cocoaheads, Minsk 36 -
Cuckoo • Source Language: Swift Code • Written in: Swift
• Generates: Swift (Mocks) https://github.com/SwiftKit/ Cuckoo Code Generators in Swift, #Cocoaheads, Minsk 37 -
Cuckoo let mock = MockGreeter() stub(mock) { stub in when(stub.greetWithMessage("Hello
world")).then { message in print(message) } } Code Generators in Swift, #Cocoaheads, Minsk 38 -
VIPER Module Generator • Source Language: String • Written in:
Ruby • Generates: Swift, Objective-C https://github.com/teambox/ viper-module-generator Code Generators in Swift, #Cocoaheads, Minsk 39 -
Generamba • Source Language: Ruby (DSL) • Written in: Ruby
• Generates: Swift, Objective-C, Xcode Project https://github.com/rambler-digital-solutions/ Generamba Code Generators in Swift, #Cocoaheads, Minsk 40 -
Protobuf Source: Protocol Buffers Language Written in: * Generates: Swift,
Any Supported Language https://github.com/alexeyxo/protobuf-swift https://github.com/google/protobuf Code Generators in Swift, #Cocoaheads, Minsk 41 -
SwiftGen Source: Xcode Files Written in : Swift Generates: Enums
for resources https://github.com/AliSoftware/SwiftGen Code Generators in Swift, #Cocoaheads, Minsk 42 -
SwiftGen // The Image type below is typealias'ed to UIImage
on iOS and NSImage on OSX enum Asset: String { case Green_Apple = "Green-Apple" case Red_Apple = "Red apple" case _2_Pears = "2-pears" var image: Image { return Image(asset: self) } } extension Image { convenience init!(asset: Asset) { self.init(named: asset.rawValue) } } Code Generators in Swift, #Cocoaheads, Minsk 43 -
R Source: Xcode Project Files Written in : Swift Generates:
Enums for resources https://github.com/mac-cain13/R.swift Code Generators in Swift, #Cocoaheads, Minsk 44 -
Helium Source : DSL in Groovy Written in : JVM
Languages Java/Kotlin/Groovy Generates: Java Library, API Client, Swift, Objective-C https://github.com/stanfy/ helium Code Generators in Swift, #Cocoaheads, Minsk 46 -
If you decided to create on Code Generators in Swift,
#Cocoaheads, Minsk 47 -
SourceKitten [{ "descriptionKey" : "advancedBy(n: Distance)", "associatedUSRs" : "s:FSi10advancedByFSiFSiSi ",
"kind" : "source.lang.swift.decl.function.method.instance", "sourcetext" : "advancedBy(<#T##n: Distance##Distance#>)", "context" : "source.codecompletion.context.thisclass", "typeName" : "Int", "moduleName" : "Swift", "name" : "advancedBy(n: Distance)" }, Code Generators in Swift, #Cocoaheads, Minsk 50 -
SourceKitten sourcekitten structure --text "struct A { func b() {}
} { "key.substructure" : [ { "key.kind" : "source.lang.swift.decl.struct", "key.offset" : 0, "key.nameoffset" : 7, "key.namelength" : 1, "key.bodyoffset" : 10, "key.bodylength" : 13, "key.length" : 24, "key.substructure" : [ ... } ], "key.offset" : 0, "key.diagnostic_stage" : "source.diagnostic.stage.swift.parse", "key.length" : 24 } Code Generators in Swift, #Cocoaheads, Minsk 51 -
Simple is better than easy • Simple is easier to
support and understand Code Generators in Swift, #Cocoaheads, Minsk 55 -
Simple is better than easy • Simple is easier to
support and understand • Easy one can be complex but easy to use Code Generators in Swift, #Cocoaheads, Minsk 56 -
Simple is better than easy • Simple is easier to
support and understand • Easy one can be complex but easy to use • Use templates Code Generators in Swift, #Cocoaheads, Minsk 57 -
Check reality • Ask if this tool is really needed?
• Ask other people too Code Generators in Swift, #Cocoaheads, Minsk 59 -
For the future generations • Document • Open Source Code
Generators in Swift, #Cocoaheads, Minsk 60 -
Source type 'Shop' message { shop_id 'string' image 'string' name
'string' description 'string' currency 'string' optional service_charge 'AdditionalCharges' optional payment_methods(type:'PaymentMethod') { sequence true required false } } Code Generators in Swift, #Cocoaheads, Minsk 62 -
Source type "dayOfWeek" spec { constraints("string") { enumeration 'sun', 'mon',
'tue', 'wed', 'thu', 'fri', 'sat' } } Code Generators in Swift, #Cocoaheads, Minsk 63 -
Entities generation public enum DayOfWeek: String { case Sun =
"sun" case Mon = "mon" case Tue = "tue" case Wed = "wed" case Thu = "thu" case Fri = "fri" case Sat = "sat" } Code Generators in Swift, #Cocoaheads, Minsk 64 -
Entities generation public struct Shop { public let shopId: String
public let image: String public let name: String public let description: String public let currency: String? public let serviceCharge: AdditionalCharges? public let paymentMethods: [PaymentMethod]? } Code Generators in Swift, #Cocoaheads, Minsk 65 -
Equatable // MARK: - Shop Equatable public func == (lhs:
Shop, rhs: Shop) -> Bool { return lhs.shopId == rhs.shopId && lhs.image == rhs.image && lhs.name == rhs.name && lhs.description == rhs.description && lhs.currency == rhs.currency && lhs.serviceCharge == rhs.serviceCharge && lhs.paymentMethods == rhs.paymentMethods } Code Generators in Swift, #Cocoaheads, Minsk 66 -
Mappings generation extension DayOfWeek: Decodable {} extension Shop: Decodable {
public static func decode(json: AnyObject) throws -> Shop { return try Shop( internalId: json =>? "internal_id" , shopId: json => "shop_id" , image: json => "image" , name: json => "name" , description: json => "description" , currency: json =>? "currency" , deliveryCharge: json =>? "delivery_charge" , paymentMethods: json =>? "payment_methods" ) } } Code Generators in Swift, #Cocoaheads, Minsk 67 -
Random structures generation extension Shop: Random { static func random()
-> Shop { return restrictedRandom() } } Code Generators in Swift, #Cocoaheads, Minsk 68 -
Random structures generation extension Shop: Random { static func restrictedRandom(
shopId: String = .random(), image: String = .random(), name: String = .random() ... ) -> Shop { return Shop( shopId: shopId, image: image, name: name ... ) } } Code Generators in Swift, #Cocoaheads, Minsk 69 -
Structures updates extension Shop { func updated( shopId: Optional<String> =
nil, image: Optional<String> = nil, name: Optional<String> = nil ... ) -> Shop { return Shop( shopId:shopId ?? self.shopId, image:image ?? self.image, name:name ?? self.name ... ) } } Code Generators in Swift, #Cocoaheads, Minsk 70 -
Generated code in action // Only shipId will be set
up let validShop = Shop.restrictedRandom( shopId: "SE2016", currency: "UAH" ) // Everything will be copied but 'shopID' property let anotherShop = validShop.updated(shopId:"123") // If we want to set up nil value let notSavedYet = validShop.updated(internalId: Optional(nil)) let notSavedYet2 = validShop.updated(internalId: .Some(nil)) Code Generators in Swift, #Cocoaheads, Minsk 71 -
From one source type 'Shop' message { shop_id 'string' image
'string' name 'string' description 'string' currency 'string' optional service_charge 'AdditionalCharges' optional payment_methods(type:'PaymentMethod') { sequence true required false } } Code Generators in Swift, #Cocoaheads, Minsk 72 -
Sum up • Code generators are here Code Generators in
Swift, #Cocoaheads, Minsk 73 -
Sum up • Engineering approach > Art Code Generators in
Swift, #Cocoaheads, Minsk 74 -
Sum up • There're always things to automate • Code
generation is one of the multiple options Code Generators in Swift, #Cocoaheads, Minsk 75 -
Sum up • Write your own if it worth it
• Please don't write another one-time-complex generator • Document well Code Generators in Swift, #Cocoaheads, Minsk 76 -
Code Generators in Swift by Paul Taykalo, Stanfy @TT_Kilew Code
Generators in Swift, #Cocoaheads, Minsk 78