통합 및 핵심 포지셔닝, 섹션 1 - 출판사 및 대표

24695 단어 swiftuiswiftios
애플의 대다수 API는 Objective-C와 위탁 모델의 시대에서 나온다.이런 점을 감안하여 우리가 직면한 도전은 어떻게 SwiftUI에 적응하는가이다.구체적으로 말하자면, 우리는 Combine를 사용하여 대표에서 발표자를 만들기를 희망한다.
예를 들어, my app Heartwitch is an Apple Watch app for live streamers.이런 상황에서 HealthKit를 사용하고 위탁 모델을 자주 심는다.그 밖에 저는 업데이트 기술을 사용하고 있습니다. 예를 들어 Vapor 4, 독립 시계 응용 프로그램, 가장 중요한 것은 SwiftUI입니다.
이 시리즈에서는 Combine의 이전 API 개편 과정을 자세히 설명합니다.구체적으로 말하자면, 우리는 기본적인 SwiftUI 응용 프로그램을 구축하여 CoreLocation으로 당신의 위도와 경도를 표시할 것입니다.여기에는 다음이 포함됩니다.
  • 에이전트에서 작성자
  • 함수 반응식 프로그래밍 변환값 사용
  • 평면 지도 및 내장 출판사 이해
  • 이 부분에서 우리는 ProtocolClass를 어떻게 만드는지 배울 것이다. 이것은 위탁 모델과 SwiftUI와Combine의 반응식 함수 프로그래밍의 중간 부분으로 삼을 것이다.

    2009년처럼 권한을 부여합니다.


    애플은 10여 년 동안 개발자들이 UI 대상에 응답하고 업데이트하며 실행할 수 있도록 위탁 모델을 자주 사용해 왔다.이런 모델은 좋은 점이 많다. 특히 Objective-C에서. 그러나 Swift와 SwiftUI가 생기면서 이런 모델은 매우 어색해진다.
    따라서 에이전트가 SwiftUI로 업데이트를 처리할 수 있는 방식으로 응답해야 합니다.
    Apple의 이전 API에서는 일반적으로 다음과 같은 내용을 볼 수 있습니다.
    protocol NSDelegate : NSObjectProtocol {
      func manager(_ manager: NSManager, doneWith data: AnyObject)
      func manager(_ manager: NSManager, grantedPermission: Bool)
    }
    class NSManager : NSObject {
      weak var delegate : NSDelegate?
    
      func requestAuthorization() {}
      func doThing () {}
    }
    
    핵심 포지셔닝의 경우 다음과 같이 볼 수 있습니다.
    protocol CLLocationManagerDelegate : NSObjectProtocol {
      func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation])
      func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus)
    }
    class CLLocationManager : NSObject {
      weak var delegate : CLLocationManagerDelegate?
    
      func requestWhenInUseAuthorization() {}
      func startUpdatingLocation () {}
    }
    
    다시 말하면 우리는 연합 출판사를 만들어야 한다. 우리의 ObservableObject 는 듣거나 대답할 수 있다.일단ObservableObject이 정상적으로 반응하면View은 상응하는 업데이트를 한다.마지막으로, 우리는 응용 프로그램에서 이 점을 보아야 한다.

    발표 서버를 설정하기 전에 ViewObservableObject 을 구축합니다.

    SwiftUI 비계


    먼저 SwiftUI 뷰 구축부터 시작합니다.이 예제에서는 SwiftUI 뷰 및 ObservableObject 를 만듭니다.
    struct LocationView: View {
      // CLLocationManager is basically a singleton so an EnvironmentObject ObservableObject makes sense
      @EnvironmentObject var locationObject: CoreLocationObject
      var body: some View {
        VStack {
          // use our extension method to display a description of the status
          Text("\(locationObject.authorizationStatus.description)")
            .onTapGesture {
              self.locationObject.authorize()
            }
          // use Optional.map to hide the Text if there's no location
          self.locationObject.location.map {
            Text($0.description)
          }
        }
      }
    }
    
    LocationView 는 위치 설명과 확장자 설명 CLAuthorizationStatus 을 사용하는 줄을 간단하게 보여 줍니다.
    extension CLAuthorizationStatus: CustomStringConvertible {
      public var description: String {
        switch self {
        case .authorizedAlways:
          return "Always Authorized"
        case .authorizedWhenInUse:
          return "Authorized When In Use"
        case .denied:
          return "Denied"
        case .notDetermined:
          return "Not Determined"
        case .restricted:
          return "Restricted"
        @unknown default:
          return "🤷‍♂️"
        }
      }
    }
    
    이제 우리의 ObservableObject 이름을 CoreLocationObject 로 정의해 봅시다.
    import Combine
    import CoreLocation
    import SwiftUI
    class CoreLocationObject: ObservableObject {
      @Published var authorizationStatus = CLAuthorizationStatus.notDetermined
      @Published var location: CLLocation?
      init() { }
    }
    
    마지막으로 다음 방법을 사용하여 응용 프로그램에 설정해야 합니다EnvironmentObject.
    LocationView().environmentObject(CoreLocationObject())
    
    이제 CoreLocation을 삽입하도록 비계 설정이 있습니다.

    공동 게시 서버로 에이전트 확장



    의뢰 모드를 사용하면 의뢰(이 예에서 CoreLocationManagerDelegate는 수신 위치를 업데이트합니다.따라서 우리ObservableObject를 위해 출판사를 만드는 것이 이상적인 목표이다.
    우리ObservableObject가 핵심 위치의 변화에 반응하기 위해서는 발표자를 만들어야 한다는 뜻이다.이 점을 감안하여 나는 이미 공인이 될 수 있는 권한을 확장했다.대표도 출판사 공장이 될 것이라는 얘기다.
    protocol CLLocationManagerCombineDelegate: CLLocationManagerDelegate {
      func authorizationPublisher() -> AnyPublisher<CLAuthorizationStatus, Never>
      func locationPublisher() -> AnyPublisher<[CLLocation], Never>
    }
    
    응용 프로그램에서 핵심 위치의 권한 수여 상태와 위도와 경도를 보여 줍니다.따라서 우리는 발표자를 위해 두 가지 방법만 실현할 수 있다.
    다음은 우리의 새로운 협의의 실현이다.
    class CLLocationManagerPublicist: NSObject, CLLocationManagerCombineDelegate {
      let authorizationSubject = PassthroughSubject<CLAuthorizationStatus, Never>()
      let locationSubject = PassthroughSubject<[CLLocation], Never>()
      func authorizationPublisher() -> AnyPublisher<CLAuthorizationStatus, Never> {
        return Just(CLLocationManager.authorizationStatus())
          .merge(with:
            authorizationSubject.compactMap { $0 }
          ).eraseToAnyPublisher()
      }
      func locationPublisher() -> AnyPublisher<[CLLocation], Never> {
        return locationSubject.eraseToAnyPublisher()
      }
      func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locationSubject.send(locations)
      }
      func locationManager(_: CLLocationManager, didFailWithError _: Error) {
        // Implement to avoid crashes
        // Extra Credit: Create a publisher for errors :/
      }
      func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        authorizationSubject.send(status)
      }
    }
    
    이 수업이 어떻게 운영되는지 분석해 봅시다.

    식자 출판사의 힘


    우리의 홍보원은 어떤 가치관도 견지할 필요가 없다.마지막으로 데이터를 CoreLocationManager 에서 ObservableObject 로 변환하는 데만 사용됩니다.따라서 우리는 PassthroughSubjectCLLocation 에 사용할 것이다.즉, CLAuthorizationStatus 수신 값을 저장하지 않고 전달하는 것이다.PassthroughSubject 속성이 있으면 우리의 의뢰는 의뢰 방법에서 받은 값을 수험자에게 발송할 수 있습니다.PassthroughSubject 첫 번째 출판사를 만드는 것은 매우 간단합니다.
    class CLLocationManagerPublicist: NSObject, CLLocationManagerCombineDelegate {
    ...
      let locationSubject = PassthroughSubject<[CLLocation], Never>()
      func locationPublisher() -> AnyPublisher<[CLLocation], Never> {
        return locationSubject.eraseToAnyPublisher()
      }
      func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        locationSubject.send(locations)
      }
    ...
    }
    
    의식해야 할 것은 유형 삭제를 실현하기 위해 CLLocation 를 사용해야 한다는 것이다.SwiftUI 및 Combine 도입에는 Swift에 대한 개선 사항이 포함됩니다.이러한 개선은 강력한 전환을 허용하여 상당히 복잡한 범용 유형을 만들어 낸다.예를 들어, 우리의 eraseToAnyPublisher 반환 유형은 다음과 같습니다.
      func authorizationPublisher() -> AnyPublisher<CLAuthorizationStatus, Never> {
        return Just(CLLocationManager.authorizationStatus())
          .merge(with:
            authorizationSubject.compactMap { $0 }
          ).eraseToAnyPublisher()
      }
    
    authorizationPublisher가 없으면 반환 유형은 다음과 같습니다.
    Publishers.Merge<Just<CLAuthorizationStatus>, Publishers.CompactMap<PassthroughSubject<CLAuthorizationStatus, Never>, CLAuthorizationStatus>>
    
    AnyPublisher와 유사하며 반환 유형은 다음과 같습니다.
    PassthroughSubject<[CLLocation], Never>
    
    마지막으로, 이것은 프로토콜을 만드는 것과 되돌아오는 형식을 상당히 복잡하게 한다.eraseToAnyPublisher의 경우 발표 서버가 어떻게 바뀌는지에 관심이 없고 결과 유형을 되돌려줍니다.
    따라서 우리의 협의는 유형을 되돌려주기만 하면 된다.마지막으로 우리는 locationPublisher 함수 변환을 간소화하고 숨길 수 있다.마찬가지로 호출ObservableObject을 실현하여 반환 유형을 줄이고 프로토콜과 일치하는 방법으로 서명합니다.
    현재 우리는 일치하는 게시자 형식을 만드는 방법을 알고 있습니다. AnyPublishers를 변환해서 보기에서 사용할 수 있도록 합니다.

    권한 부여 상태를 게시자로 변환


    우리eraseToAnyPublisher는 CoreLocation의 값을 반영하지만 eraseToAnyPublisher는 CoreLocation의 상태와 동기화되지 않습니다.따라서 초기 상태와 CLAuthorizationStatu 수신된 모든 내용을 포함한 코드를 작성해야 합니다.
      func authorizationPublisher() -> AnyPublisher<CLAuthorizationStatus, Never> {
        return Just(CLLocationManager.authorizationStatus())
          .merge(with:
            authorizationSubject
          ).eraseToAnyPublisher()
      }
    
    locationSubject 에 업데이트를 보낼 때 authorizationSubject 를 통해 초기 상태에 접근해야 합니다.다행히도 Combine 사용PassthroughSubject은 하나의 값에 내장 게시기를 제공했다.CoreLocationManagerDelegate 발표의 초기 값을 제시했지만, authorizationStatus 중 나머지 발표 값을 포함해야 합니다.따라서, 우리는 CLLocationManager.authorizedStatus 초기 값을 우리 Just 의 결과와 연결할 수 있다.

    우리는 지금 이미 출판사 공장을 세웠다.
    Combine에 대한 자세한 내용은 나와 Donny Wals의 팟캐스트 에피소드를 참조하십시오.

    Donny Wals와의 실제 결합


    인증 응용 프로그램.표시





    브라우저에서 오디오 요소를 지원하지 않습니다.





    1x
    초기화 중...
    ×

    다음은 뭐예요?


    이 시리즈의 다음 부분에서 우리는 JustPassthroughSubject에서 어떻게 이 실현을 사용하는지 배울 것이다.구체적으로 말하자면, 우리는 반응 함수 프로그래밍에서 함수 프로그래밍의 위력을 토론할 것이다.즐기다

    좋은 웹페이지 즐겨찾기