I have 2 versions of the same model in the project (and I can't get rid of the legacy one). It is Customer (legacy code) and struct CustomerModel - modern Swift implementation of the model.
I have a custom UITableViewCell which used to have setup(withCustomer: CustomerModel) method. It worked well for a new model, but now I need to use legacy one to setup same cells.
I decided to define CustomerDisplayable protocol and make both models conform it.
Here is the code:
Customer.h
@interface Customer : NSObject
@property (nonatomic, strong) NSString* name;
@property (nonatomic, strong) NSString* details;
@end
CustomerModel.swift
struct CustomerModel {
let name: String
let details: String?
init(withJSON json: [String: Any]) {
name = json["name"] as! String
details = json["details"] as? String
}
}
CustomerDisplayable.swift
protocol CustomerDisplayable {
var name: String { get }
var details: String? { get }
var reviewCount: Int { get }
var reviewRating: Double { get }
}
extension Customer: CustomerDisplayable {
var reviewCount: Int { return 100 }
var reviewRating: Double { return 4.5 }
}
extension CustomerModel: CustomerDisplayable {
var reviewCount: Int { return 100 }
var reviewRating: Double { return 4.5 }
}
I expected that as Customer.h has already properties name & details - it will conform this protocol and extension above will work. But I get a compiling error in my extension:
Type 'Customer' does not conform to protocol 'CustomerDisplayable'.
Xcode offers a quick fix - Protocol requires property 'name' with type 'String'; do you want to add a stub.
If I agree Xcode add stubs I end up with name and details computable getters but Xcode shows new compile errors:
extension Customer: CustomerDisplayable {
var details: String? {
return "test"
}
var name: String {
return "test"
}
var reviewCount: Int { return 100 }
var reviewRating: Double { return 4.5 }
}
- 'details' used within its own type
- Getter for 'name' with Objective-C selector 'name' conflicts with the previous declaration with the same Objective-C selector
Any ideas how to solve this problem? I really want to have this protocol and abstract interface for both model representations.
The only solution I came to is to rename properties in CustomerDisplayable
NOTE: Real models are much more complex, but this code is demonstrating the problem.