Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No exact matches in call to instance method 'append' in swift

Tags:

arrays

swift

Tried to combine or merging two model to one model 1st model = items [ InboxModel]. (My own Inbox) 2nd model = items2 [MoInboxModel] (SDK Inbox)

1st + 2nd -> combinedItems

private var items: [InboxModel] = []
private var items2: [MoInboxModel] = []
private var combinedItems: [combinedInboxModel] = []

struct InboxModel {
    let id: String
    let title: String
    let message: String
    let date: Date
}

struct MoInboxModel {
    let id: String
    let title: String
    let message: String
    let date: Date
}

struct combinedInboxModel {
    let id: String
    let title: String
    let message: String
    let date: Date
}

self?.combinedItems.append(self?.items). //No exact matches in call to instance method 'append
self?.combinedItems.append(contentsOf: self?.items2 ?? []) //No exact matches in call to instance method 'append

Why there is an error while merge it ? How to merge it correctly?

like image 396
lauwis Avatar asked Oct 27 '25 07:10

lauwis


2 Answers

You have three unrelated types - InboxModel, MoInboxModel and combinedInboxModel (Which should be CombinedInboxModel. Even though they all have properties with the same name, they are different types.

There is no append function on an array of combinedInboxModel that accepts an array of InboxModel or MoInboxModel.

You could use map on each of your two input arrays to convert them to an array of CombinedInboxModel which you can then put into combinedItems.

Presumably you are writing this code in a closure, which is why you have a weak self. Best to deal with that first and then process your arrays.

guard let self = self else {
    return
}

self.combinedItems = self.items.map { CombinedInboxModel(id:$0.id,title:$0.title,message:$0.message,date:$0.date) }

let items2 = self.items2.map { CombinedInboxModel(id:$0.id,title:$0.title,message:$0.message,date:$0.date) }

self.combinedItems.append(contentsOf:items2)

You haven't shown where items and items2 come from; Is it possible just to fetch them as instances of the same struct to start with?

like image 129
Paulw11 Avatar answered Oct 28 '25 22:10

Paulw11


The fact that you have three structs with the same properties is a bit fishy. I would consider a different design if I were you.

However, if you must go with this approach, you might want to consider starting with a protocol and getting rid of the combinedInboxModel struct.

protocol InboxModelable {
    var id: String { get }
    var title: String { get }
    var message: String { get }
    var date: Date { get }
}

Now make your two structs conform to InboxModelable.

struct InboxModel: InboxModelable {
    let id: String
    let title: String
    let message: String
    let date: Date
}

struct MoInboxModel: InboxModelable {
    let id: String
    let title: String
    let message: String
    let date: Date
}

Since both of your types conform to InboxModelable you can directly store both types in an array of type Array<InboxModelable> without having to map the elements.

class SomeClass {
    private var items: [InboxModel] = []
    private var items2: [MoInboxModel] = []
    private var combinedItems: [InboxModelable] = []

    func combineItems() {
        doSomething { [weak self] in
            guard let self = self else { return }
            self.combinedItems.append(contentsOf: self.items)
            self.combinedItems.append(contentsOf: self.items2)
        }
    }
}
like image 32
Rob C Avatar answered Oct 28 '25 22:10

Rob C



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!