6

I am facing an error while implementing protocol.

I have declared a protocol as below in a file named as 'TransactionListViewViewModelItem.swift'. Below is what I have in this file

protocol TransactionListViewViewModelItemProtocol: Comparable {
    var transactionBookingDate: Date { get }
    var transactionPartnerDisplayName: String { get }
}

struct TransactionListViewViewModelItem: TransactionListViewViewModelItemProtocol {

    static func < (lhs: TransactionListViewViewModelItem, rhs: TransactionListViewViewModelItem) -> Bool {
        return lhs.transactionBookingDate < rhs.transactionBookingDate
    }
    
    static func == (lhs: TransactionListViewViewModelItem, rhs: TransactionListViewViewModelItem) -> Bool {
        return lhs.transactionBookingDate == rhs.transactionBookingDate
    }
    
    var transactionBookingDate: Date {
        transactionModel.transactionDetail.bookingDate.getTransactionDate()
    }
    
    var transactionPartnerDisplayName: String {
        transactionModel.partnerDisplayName
    }
    
    private let transactionModel: Transaction
    
    // MARK: - init
    init(transaction: Transaction) {
        transactionModel = transaction
    }
}

Now When I tried to use above in my viewmodel class TransactionListViewViewModel.swift as below

protocol TransactionListViewViewModelProtocol {
    init(fileName: String)
    var numberOfRows: Int { get }
    func transactionItem(at indexPath: IndexPath) ->  TransactionListViewViewModelItemProtocol
}

class TransactionListViewViewModel: TransactionListViewViewModelProtocol {

    private var arrayOfTransactions: [TransactionListViewViewModelItemProtocol] = []
    // MARK: - init
    required init(fileName: String) {
        fetchAllTransactionsModel(from: fileName)
    }

  /*
   rest code....
  */
}

I got error as Use of protocol 'TransactionListViewViewModelItemProtocol' as a type must be written 'any TransactionListViewViewModelItemProtocol'

Please guide me what am I doing wrong.

Below is error screenshot enter image description here

HangarRash
  • 7,314
  • 5
  • 5
  • 32
Nupur Rawat
  • 115
  • 1
  • 2
  • 5
  • 2
    You haven't added the required keyword `any` https://github.com/apple/swift-evolution/blob/main/proposals/0335-existential-any.md – Paulw11 Jan 19 '23 at 21:02
  • @Paulw11 this is only valid for swift 5.6 and above, what would be the solution for lower versions of swift? – Mike.R Feb 28 '23 at 20:07
  • You won't get this error on lower versions of swift – Paulw11 Feb 28 '23 at 20:11

1 Answers1

1

It's because the protocol you want to return is assigning another protocol. I'm not sure what related to Comparable is triggering that**, but you can fix it by removing Comparable assignment OR using Generics in the follow way (explicitly specialization):

protocol TransactionListViewViewModelProtocol {
    init(fileName: String)
    var numberOfRows: Int { get }
    func transactionItem<T: TransactionListViewViewModelItemProtocol>(at indexPath: IndexPath) -> T
}

** If you open Comparable definition it's assigning to Equatable. Equatable in their methods receive as parameter Self. Comparable has method receiving Self too. The example below mirror that handling:

protocol chaining using Self

If you use Generics it will be triggered too:

same error from previous, but using Generics

In that cases we have to explicitly specify by:

protocol ABCD {
    func method<T: ProtocolThatUsesGenerics>() -> T
}

protocol UsingSecondLayer {
    func method<T: SecondLayerUsingSelf>() -> T
}
Andre Lara
  • 29
  • 1