58

UPDATE: Use structs and not classes. Struct is better in many ways has got an initializer of its own.

This is my model class. Is it possible to create the init method automatically? Everytime I have to initialize all the variables one by one and it costs a lot of time.

class Profile {

    var id: String
    var name: String
    var image: String

    init(id: String, name: String, image: String) {
        self.id = id
        self.name = name
        self.image = image
    }
}

I want self.id = id and other variables to initialize automatically.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Bhavuk Jain
  • 2,167
  • 1
  • 15
  • 23
  • 6
    Kinda bizarre this doesn't exist... – David P Feb 23 '18 at 04:38
  • @Chicken You should use structs. They have so many benefits as compared to classes. – Bhavuk Jain Feb 23 '18 at 12:18
  • I also need Objective-C compatibility. – David P Feb 26 '18 at 01:02
  • Now that some time went by, I'm facing another issue with this when using structs: If you have some default values assigned the internal initializer works well on Swift 5+. But on Swift 4 and below you have to add an initializer manually. So the accepted answer is gold. just quickly change from class to struct, do the refactor thingy, change it back to struct and no hassle. Note: Just for downwards compatibility necessary. – Tomte Mar 20 '20 at 10:27

4 Answers4

114

Update As of Xcode 11.4

You can refactor (right-click mouse menu) to generate the memberwise initializer for class and struct.

Note that struct automatic initializers are internal. You may want to generate memberwise initializer when defining a module to make it public.

Right-click > Refactor > 'Generate Memberwise Initializer'

xcode generate memberwise initialization

For older Xcode

There are handy plugins:

https://github.com/rjoudrey/swift-init-generator https://github.com/Bouke/SwiftInitializerGenerator

TT--
  • 2,956
  • 1
  • 27
  • 46
Moris Kramer
  • 1,490
  • 1
  • 12
  • 13
  • swiftinitializergenerator worked perfectly for me, thank you – Christian Wolf Alves Hess Nov 20 '18 at 18:43
  • @TangMonk `13.3.1` is an operating system. You mean Xcode 11.3, Yes only in 11.4 for structs and classes. Below that only for aclass. You can use plugins or rename struct to class temporly. – Moris Kramer Mar 23 '20 at 15:11
  • I an using Version 11.3.1 (11C504) for Xcode, the 11.4 seems in beta – Moon soon Mar 24 '20 at 09:28
  • What a cool feature. It is really handy for adding initializers for view models. It helps to get rid of this boring task. Thanks for your hint. – Justin Apr 10 '20 at 07:09
  • Do you know what could make the refactor options be blurred out? I right click on the class > Refactor > all options are blurred out my code compiles, I am on Xcode 11.4. – Zorayr May 09 '20 at 19:03
  • This one saves me a lot off time, didn't know you had to click on the class/struct name first. – Burgler-dev Nov 21 '20 at 05:17
37

Given the following class (or for structs if temporarily change the keyword struct to class and after refactor set back to struct):

class MyClass {
    let myIntProperty: Int
    let myStringProperty: String
    let myOptionalStringProperty: String?
    let myForcedUnwrappedOptionalStringProperty: String!
}

Go to Xcode and:

  1. Double click the class name
  2. Right click
  3. Refactor
  4. Generate Member-wise Initializer

Above steps look like this:

enter image description here

Just a tiny second later, Xcode generates this initializer:

internal init(myIntProperty: Int, myStringProperty: String, myOptionalStringProperty: String?, myForcedUnwrappedOptionalStringProperty: String?) {
    self.myIntProperty = myIntProperty
    self.myStringProperty = myStringProperty
    self.myOptionalStringProperty = myOptionalStringProperty
    self.myForcedUnwrappedOptionalStringProperty = myForcedUnwrappedOptionalStringProperty
}
J. Doe
  • 12,159
  • 9
  • 60
  • 114
  • 2
    This works well, but note that it only works for `class` declarations, not `struct` declarations. – Rudedog May 06 '19 at 20:11
  • 3
    Well, indeed doesnt work for structs, but you can change for a moment `struct` to `class`, generate the intializer and make it again a `struct` ;). – tyoc213 Oct 23 '19 at 01:09
  • Doesn't work for me sadly. My xCode does "boop" sound and nothing happens.. – Aetherna Apr 16 '21 at 21:59
11

No, there is no such feature for classes. But, if you design this as a struct, you get an memberwise initializer for free — assuming you don't define others initializers yourself.

For instance:

struct Point {
    var x: Float
    var y: Float
}
...
var p = Point(x: 1, y: 2)

From The Swift Programming Language book:

Structure types automatically receive a memberwise initializer if they do not define any of their own custom initializers. Unlike a default initializer, the structure receives a memberwise initializer even if it has stored properties that do not have default values.

The memberwise initializer is a shorthand way to initialize the member properties of new structure instances. Initial values for the properties of the new instance can be passed to the memberwise initializer by name.

Community
  • 1
  • 1
Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
  • @BhavukJain If my answer solved your question, pls be sure to mark it as the accepted answer when you get a chance... thanks man! – Paulo Mattos May 10 '17 at 16:14
  • 2
    I'll upvote it because you mentioned something I didn't know. But still, I'm looking for an answer by how classes can achieve this. Maybe someone has created a tool for it so it can be used directly. There must be a way! – Bhavuk Jain May 11 '17 at 11:19
  • @BhavukJain The answer, circa *Swift 3.1*, is simply no, there isn't such feature for classes :( And peeking [into the future](https://apple.github.io/swift-evolution/) it seems no such capability is in the roadmap either ([this one was close](https://github.com/apple/swift-evolution/blob/master/proposals/0018-flexible-memberwise-initialization.md) but it was postponed). Of course, you could always use a *code generator* for this but it seems too much trouble if you ask me ;) – Paulo Mattos May 11 '17 at 11:40
  • 1
    Unfortunately this doesn't work if you want to make the struct accessible from another module as the memberwise initialisers are set to internal access and require you to recreate the memberwise initialiser by hand (or the tools listed above). – Daniel Wood May 10 '19 at 11:12
2

You can use struct if you want automatically created init without actual need to define it.

If you want to define it as fast as possible for classes, you can use automatic initializer completion luckily introduced in Xcode 14 (source - 60399329)

enter image description here

Robert Dresler
  • 10,580
  • 2
  • 22
  • 40