簡體   English   中英

使“可識別”協議向后兼容

[英]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 包,所以您很不走運。

但是,如果您稍微重構一下代碼,您可能能夠同時支持IdentifiableCompatibilityIdentifiable並減少重復:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM