How can I make the memberwise initialiser public, by default, for structs in Swift?

SwiftInitialization

Swift Problem Overview


I have a Swift framework that defines a struct:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String
}

However, I can't seem to use the implicit memberwise initialiser from another project that imports the library. The error is:

> 'CollectionTO' cannot be initialised because it has no accessible initialisers

i.e. the default synthesized memberwise initialiser is not public.

var collection1 = CollectionTO(index: 1, title: "New Releases", description: "All the new releases")

I'm having to add my own init method like so:

public struct CollectionTO {
    var index: Order
    var title: String
    var description: String

    public init(index: Order, title: String, description: String) {
        self.index = index;
        self.title = title;
        self.description = description;
    }
}

... but is there a way to do this without explicitly defining a public init?

Swift Solutions


Solution 1 - Swift

Quoting the manual:

> "Default Memberwise Initializers for Structure Types The default memberwise initializer for a structure type is considered private if any of the structure’s stored properties are private. Otherwise, the initializer has an access level of internal.

> As with the default initializer above, if you want a public structure type to be initializable with a memberwise initializer when used in another module, you must provide a public memberwise initializer yourself as part of the type’s definition."

Excerpt from "The Swift Programming Language", section "Access Control".

Solution 2 - Swift

While it is not possible to have the default memberwise initializer at least you can make one quickly with the following steps:

UPDATE: Xcode 11 and later

As mentioned by Brock Batsell on the comments, for Xcode 11 and later all you need to is this:

  • Right click the class or struct name and choose refactor -> Generate Memberwise Initializer

Xcode 10 and earlier answer

  1. Make the object a class temporarily instead of a struct

  2. Save

  3. Right click the class name and choose refactor -> Generate Memberwise Initializer

  4. Change it back to a struct

Solution 3 - Swift

We now have a ruby gem  to parse a complete swift data model file, line-by-line, and add public access modifiers, public member-wise default initializers, and other things into a separate auto-generated output swift file.

This gem is called swift_republic

Please check out the following documentation for running this gem:

https://github.com/mehul90/swift_republic

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbandejapaisaView Question on Stackoverflow
Solution 1 - SwiftbandejapaisaView Answer on Stackoverflow
Solution 2 - SwiftJP AquinoView Answer on Stackoverflow
Solution 3 - SwiftMehul ParmarView Answer on Stackoverflow