[英]Making `Identifiable` protocol backwards compatible
問題
Apple 僅在 iOS 13+ 中提供可Identifiable
。 這是一個非常有用的協議,但是我最終使用了我自己的名為CompatibilityIdentifiable
的“可識別”協議。
public protocol CompatibilityIdentifiable {
associatedtype Id: Equatable
var id: Id { get }
}
問題:
有什么方法可以使我的自定義CompatibilityIdentifiable
也符合 iOS 13+ 上的Identifiable
?
背景:
在常規項目中,這沒有用。 但是在 SPM 包中,這意味着很多,因為我可以為CompatibilityIdentifiable
實現與Identifiable
相同的行為,而無需復制我的代碼。
下面是一個例子:
extension TableViewHelper where Section: CompatibilityIdentifiable {
public func replace(sections: [Section], with animation: UITableView.RowAnimation = .automatic) {
replaceSections(with: animation) { oldSection in
return sections.first(where: { $0.id == oldSection.id })
}
}
}
如果我可以簡單地使CompatibilityIdentifiable
符合Identifiable
我可以將Identifiable
用於 iOS 13+ 的項目
老實說,我認為這是不可能的,除非我只是像這樣復制和粘貼代碼:
@available(iOS 13, *)
extension TableViewHelper where Section: Identifiable {
public func replace(sections: [Section], with animation: UITableView.RowAnimation = .automatic) {
replaceSections(with: animation) { oldSection in
return sections.first(where: { $0.id == oldSection.id })
}
}
}
我不會這樣做,因為我們正在談論很多功能。 所以,如果沒有辦法,我將繼續在我未來的項目和 SPM 中使用CompatibilityIdentifiable
不幸的是,無法讓您的協議從Identifiable
繼承,而只能從 iOS 13 及更高版本繼承。
原因是您不能有兩個相同協議的聲明,一個用於 iOS 12-,一個用於 iOS 13+。
使用 Objective-C 協議,這可能可以通過一些#ifdef
舞蹈來實現,但是由於Identifiable
是一個僅限 Swift 的協議,而且由於您的目標是 Swift 包,所以您很不走運。
但是,如果您稍微重構一下代碼,您可能能夠同時支持Identifiable
和CompatibilityIdentifiable
並減少重復:
extension TableViewHelper {
// mind the `internal` access modifier here (explicitly written)
internal func replace(sectionIds: [Section.Id], with animation: UITableView.RowAnimation = .automatic) {
replaceSections(with: animation) { oldSectionId in
return sections.first(where: { $0.id == oldSectionId })
}
}
public func replace(sections: [Section], with animation: UITableView.RowAnimation = .automatic) where Section: CompatibilityIdentifiable {
replace(sectionIds: sections.map(\.id), with: animation)
}
@available(iOS 13, *)
public func replace(sections: [Section], with animation: UITableView.RowAnimation = .automatic) where Section: Identifiable {
replace(sectionIds: sections.map(\.id), with: animation)
}
}
即使兩個公共函數看起來一樣,但它們只有一行代碼,在代碼重復的經濟性上更容易掌握。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.