rocklyve
rocklyve

Reputation: 143

Swift 4: struct in struct

I have a problem with creating a struct.

My struct:

public struct Device: Codable {
    let data: DeviceData
    let meta: Meta?
}

public struct DeviceData: Codable {
    let deviceID: String?
    let type: String?
    let attributes: Attributes?

    private enum CodingKeys: String, CodingKey {
        case deviceID = "id"
        case type
        case attributes
    }
}

public struct Attributes: Codable {
    let name: String?
    let asdf: String?
    let payload: Payload?
}

public struct Payload: Codable {
    let example: String?
}

public struct Meta: Codable {
    let currentPage: Int?
    let nextPage: Int?
    let deviceID: [String]?
}

When I now would like to create an element of this struct with:

var exampleData = Device(
        data: DeviceData(
            type: "messages",
            attributes: Attributes(
                name: "Hello World",
                asdf: "This is my message",
                payload: Payload(
                    example: "World"
                )
            )
        ),
        meta: Meta(
            deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
        )
    )

I will get an error. Cannot specify this error in detail, because when I delete the "meta" element, because it's optional, another error occures... The error message for this specific code is:

Extra argument 'meta' in call

I hope that someone can help me.

Upvotes: 1

Views: 435

Answers (2)

CRD
CRD

Reputation: 53000

You have omitted arguments to both your DeviceData and Meta initializers. In a comment on another answer you ask:

do I have to add them and set them to nil, even if they are optional? maybe that's my problem!

You can do that, e.g. something like:

meta: Meta(currentPage: nil,
           nextPage: nil,
           deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
          )

Alternatively you can write your own initializer rather than rely on the default memberwise one, and supply default values there instead of on each call e.g. something like:

init(currentPage : Int? = nil, nextPage : Int? = nil, deviceID : [String]? = nil)
{
   self.currentPage = currentPage
   self.nextPage = nextPage
   self.deviceID = deviceID
}

Your original call, which omitted currentPage and nextPage, would then be valid and would set those two to nil.

HTH

Upvotes: 2

Alexander
Alexander

Reputation: 63272

You forgot the deviceID: named arguments of your call to DeviceData.init(deviceID:type:attributes:), and you also forgot the currentPage and nextPage named arguments to Meta.init(currentPage:nextPage:deviceID).

Here's a sample that compiles:

var exampleData = Device(
    data: DeviceData(
        deviceID: "someID",
        type: "messages",
        attributes: Attributes(
            name: "Hello World",
            asdf: "This is my message",
            payload: Payload(
                example: "World"
            )
        )
    ),
    meta: Meta(
        currentPage: 123,
        nextPage: 456,
        deviceID: ["asfd-asdf-asdf-asdf-asdfcasdf"]
    )
)

Upvotes: 2

Related Questions