0

스위프트 3으로 업그레이드하는 IOS 프레임 워크가 있습니다. API의 메소드 서명이 이전 버전과의 호환성을 유지하면서 메서드에 첫 번째 명명 된 매개 변수를 사용하는 Swift 3 규칙을 따르길 바랍니다. 새 API 메소드 서명을 추가하고 이전 API 메소드 서명을 사용 중지하는 것으로 충분합니다. 하지만 위임자가 사용하는 프로토콜로이를 처리하는 가장 좋은 방법은 무엇입니까?Swift 3 업그레이드에 대한 프로토콜 폐기

스위프트 2.x를위한 API : 스위프트 3.x를위한

@objc(FooManager) 
public class FooManager { 
    public var delegate: FooManagerDelegate? 
    public func saveFoo(foo: Foo) { 
    ...  
    delegate?.didSaveFoo(foo) 
    } 
... 
} 

@objc public protocol FooManagerDelegate { 
    @objc optional func didSaveFoo(foo: Foo) 
} 

새로운 API : 위의 솔루션이 작동

@objc(FooManager) 
public class FooManager { 
    public var delegate: FooManagerDelegate? 

    @available(*, deprecated, message: "use didSave(foo: foo)") 
    public func saveFoo(foo: Foo) { 
    ...  
    delegate?.didSaveFoo(foo) 
    } 
    public func save(foo: Foo) { 
    ...  
    delegate?.didSave(foo: foo) 
    } 
... 
} 

@objc public protocol FooManagerDelegate { 
    @objc optional func didSaveFoo(foo: Foo) 
    @objc optional func didSave(foo: Foo) 
} 

하지만 은 어떤 중단 경고를 제공하지 않습니다 사용자가 이전 대리자 메서드을 계속 사용하기 위해 새 대리자를 만들고 이전 대리자 클래스를 사용하지 않을 수도 있지만 비표준 대리자 클래스 및 속성 명명이 필요합니다. 내 FooManager 이렇게 예쁘게이 싫어 :

public class FooManager { 
    @available(*, deprecated, message: "use swift3delegate") 
    public var delegate: FooDelegate? 
    public var swift3delegate: Swift3FooDelegate? 

이전 버전과의 호환성을 유지하면서 새로운 프로토콜의 메소드 서명에 사용자를 마이그레이션하기위한 더 나은 솔루션이 있습니까?

답변

1

Swift (또는 Objective-C?)에서 내 지식을 정확히 요구하는 것은 불가능합니다. 인용 response to a related question :

MyProtocol을 준수하고 (myOldFunction를 구현) 수업이 프로토콜의 일부가 아닌 함수와 속성을 구현 아무 문제가 없습니다 것입니다 모든 클래스에 중단 경고를 던지고 주요 문제.

즉, 프로토콜의 방법은 반드시 방법 청사진은 보편적으로 피해야하는 것을 의미하지 않을되지 않습니다 것을, 단지 해당 프로토콜 문제의 메서드 또는 속성에 대한 적합성의 목적을 위해 것을 의미 할 수있다 현재 사용 중지되었습니다.

나는이 점을 완전히보고 싶다. 그러나이 기능을 원한다. 그러나 내 지식으로는 스위프트 3은 적어도 그것을 제공하지 않는다. (내 지식에는 목표 -C도 없다).

이 경우 하나의 솔루션은 전체 프로토콜을 사용 중지하고 Swift 3 코드에서 준수 선언을하는 데 필요한 새로운 프로토콜을 생성하는 것입니다.

@available(*, deprecated, message="use ModernX instead") 
protocol X {} 

class A: X {} 

을 ... 당신의 ModernX 프로토콜에 간단하게 사용되지 않는 방법 (들)을 제외한 모든 방법을 포함한다 : 그래서,이 작동합니다. 사용되지 않는 방법없이 기본 프로토콜을 사용하면이 약간 덜 투박하게,하지만 확실히 꽤 보일러 무거운 해결 방법입니다 수 :

protocol BaseX { 
    func foo() 
    func bar() 
} 

@available(*, deprecated, message: "Use ModernX instead") 
protocol X: BaseX { 
    func theDeprecatedFunction() 
} 

protocol ModernX: BaseX { 
    func theModernFunction() 
} 

// you'll get a deprecation warning here. 
class A: X { 
    func foo() {} 
    func bar() {} 

    func theDeprecatedFunction() { 
    } 
} 
+0

덕분에, 기본 프로토콜을 사용하는 아이디어가 도움이됩니다. 그렇게하면 관리자 클래스에 하나의'delegate' 속성 만 있으면됩니다. 나는 재미있는 이름으로 새로운 프로토콜을 만들 필요가 없었 으면 좋겠다. Swift 2 프로토콜에는 내가 사용하고 싶은 이름이있다. :( – davidgyoung

+0

자신의 코드가 동일한 대상/프로젝트/작업 공간 (예 : 검색 및 바꾸기가 간단한 설정)에있는 프로토콜의 유일한 구현 인 경우 언제든지 이름을 "... Legacy " 또는 뭔가.하지만 그래, 나는 그것이 다른 방법 으로이 해결 방법에 흥분한다고 말 할 수 없다는 단점은 깔끔하게 단위 (그냥 폐기 된 물건과 함께 프로토콜)에 비추어 물건을 분리. – mz2