Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

public struct in framework init is inaccessible due to 'internal' protection level in compiler

I have a struct in a framework called "MyFramework"

public struct ShipmentPackage:Encodable {   let package_code:String   let weight:Float } 

Then when I try to create a ShipmentPackage in another project/framework

import MyFramework let onePackage = ShipmentPackage(package_code:"BX",weight:100) 

I got an error message 'ShipmentPackage' initializer is inaccessible due to 'internal' protection level I come to this link https://forums.swift.org/t/public-struct-init-is-unexpectedly-internal/5028

I tried to change my code to following:

1st attempt:

public struct ShipmentPackage:Encodable {   let package_code:String   let weight:Float   public init(package_code:String,weight:Float){     self.package_code = package_code     self.weight = weight   } } 

2nd attempt:

public struct ShipmentPackage:Encodable {   public let package_code:String   public let weight:Float   public init(package_code:String,weight:Float){     self.package_code = package_code     self.weight = weight   } } 

Also I tried to changing around the package_code and weight to public, but none of above works, I got error messages when compile

<unknown>:0: error: 'init' is inaccessible due to 'internal' protection level <unknown>:0: note: 'init' declared here <unknown>:0: error: 'init' is inaccessible due to 'internal' protection level 

Any hint would be appreciated!

like image 408
Qiquan Lu Avatar asked Feb 13 '19 15:02

Qiquan Lu


People also ask

What is public init in Swift?

When you mark public , the thing gets available outside of the framework in which your code has been implemented whereas init() {} is a swift initializer that is responsible for ensuring the object is fully initialized. Basically initializers are called to create a new instance of a particular type.

How do you initialize a struct in Swift?

An initializer is a special type of function that is used to create an object of a class or struct. In Swift, we use the init() method to create an initializer. For example, class Wall { ... // create an initializer init() { // perform initialization ... } }

What is Memberwise initializer in Swift?

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. The example below defines a structure called Size with two properties called width and height .


1 Answers

Lesson learned: all public struct need a public init

That's not quite exact. The documentation states:

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. Likewise, if any of the structure’s stored properties are file private, the initializer is file private. Otherwise, the initializer has an access level of internal.

So the build-in memberwise initializer is only available within the package. If you don't provide a public initializer, you won't be able to create your struct from outer space.

public struct YourFrameworkStruct {     let frameworkStructProperty: String!     /// Your public structs in your framework need a public init.     ///      /// Don't forget to add your let properties initial values too.     public init(frameworkStructProperty: String) {         self.frameworkStructProperty = frameworkStructProperty     } } 
like image 152
Andreas Oetjen Avatar answered Sep 20 '22 23:09

Andreas Oetjen