Combine에서 게시자의 오류를 처리하는 가장 좋은 방법은 무엇입니까? (CoreLocation에서 제목 업데이트 게시)

곤자 노티스

나는 기반으로 제목을 업데이트 그것의 나침반 응용 프로그램 작업을 한 제목 변경 및 게시에 대한 이러한 변화에 대처하는 게시자를 생성합니다.

저는 리 액티브 프로그래밍을 처음 접했지만 제가 겪고있는 문제는 일반적인 문제인 것 같아서 게시하고 누군가가 도움을 줄 수 있는지 확인하고 싶었습니다.

때로는 게시자의 새 제목이 나오고 UI를 업데이트하면서 잠시 동안 작동하지만 작동을 멈 춥니 다. 다른 경우에는 업데이트를 시작하지 않습니다 (헤딩 업데이트 전에 오류가 전달됨). 두 경우 모두 실패 완료 이벤트가 게시자에게 전송되기 때문에 이벤트가 중지되는 것이 합리적입니다.

func locationManager(_ manager: CLLocationManager,
                     didFailWithError error: Error) {

    headingPublisher.send(completion: Subscribers.Completion.failure(error))

    print("error: \(error.localizedDescription)")
}

먼저, 이러한 오류가 무엇인지 알아 내고 더 잘 처리 할 수 ​​있도록 노력하고 있습니다. 오류가 게시자를 중지 할 가치가 있는가? 게시자가 중지하더라도 제목 업데이트가 오류 후에 재개되기 때문에 제목 업데이트 중간에 어떤 종류의 오류가 발생할 수 있는지 궁금합니다. 나는 오류를 인쇄하려고 시도했지만 내가 얻는 것은 이것이 도움이되지 않는 것 같습니다.error: The operation couldn’t be completed. (kCLErrorDomain error 0.)

나는 iOS를 잘하지 못하므로 누군가가 여기에서 더 나은 오류 설명을 얻는 방법에 대한 제안이 있으면 알려주십시오.

둘째, 구독에서 게시자의 오류를 무시할 수있는 방법이 궁금합니다. 그래야만 .sink한다면 오류가 있어도 제목 업데이트를 계속받을 수 있습니다. 다음은 예제를 기반으로 한 내 게시자 코드입니다.

    _ = headingProxy
        .publisher
        .receive(on: RunLoop.main)
        .sink(receiveCompletion: { completion in },
              receiveValue: { [weak self] (heading) in
                self?.currentHeadingAccuracy = heading.headingAccuracy
                self?.currentHeading = heading.trueHeading
        })
        .store(in: &cancellableSet)

나는 게시자에게 오류를 보낼 수 없다는 것을 알고 있지만 (그렇게해야합니까? 오류를 보내지 않는 제목 업데이트만을위한 특정 게시자가 있습니까?)이 작업을 수행 한 사람이 오류를 보낸 사람을 포함한다고 가정합니다. 타당한 이유가 있고 대신 구독 측에서 처리하는 것이 모범 사례이거나 오류 후 복구를위한 몇 가지 모범 사례가있을 수 있습니다.

길 버먼

지적했듯이 오류가 발생하면 항상 기성 연산자로 빌드 된 결합 파이프 라인이 종료됩니다. 이것은 버그가 아니라 기능입니다. 무엇 특히 놀라운 수 있습니다하면 같은 오류 처리 연산자를 사용하는 경우 파이프 라인도 끝날 것입니다 catchreplaceError.

에서 오류가 발생할 수있는 파이프 라인의 모든 부분을 래핑하여 파이프 라인을 오류에 복원 할 수 있습니다 flatMap.

메인 파이프 라인을 "외부"파이프 라인으로 생각하고 파이프 라인을 flatMap"내부"파이프 라인으로 감싼다 고 생각하세요 . 외부 파이프 라인의 오류 유형이 Never이고 값을 영원히 처리 할 수 있는지 확인하십시오 .

숫자의 제곱을 반환하는 끝점을 고려하십시오.

let myNumberPublisher = PassthroughSubject<Int, Never>()

// Outer pipeline will never error (the Error type is Never):
myNumberPublisher
  .map(String.init) // convert to string
  .flatMap { number in
    // Inner pipeline can error:
    URLSession.shared.dataTaskPublisher(for: URL(string: "https://square?n=\(number)")!)
      .replaceError(with: "Oopsies")
      .map { answer in "The answer is \(answer)" }
  }
  .sink { result in print(result) }

myNumberPublisher.send("5")
// => The answer is 25
myNumberPublisher.send("3") // assume the endpoint errors here
// => The answer is Oopsies
myNumberPublisher.send("6")
// => The answer is 36


flatMap귀하의 경우에 사용하려면 게시자를 제공하는 클래스에서 오류가 발생할 때마다 새 게시자를 요청해야 할 수 있습니다.

또는 오류 유형 headingPublisher을 갖도록 수정할 수 있습니다 Never. 이 경로로 이동하면 .NET Framework를 제공하는 객체에서 오류를 처리해야합니다 headingPublisher.

또 다른 옵션은 두 게시자에게 값을 제공하고 다른 게시자에게 오류를 제공하는 것입니다.

  • AnyPublisher<ValueType, Never>
  • AnyPublisher<Error, Never>

이러한 옵션은 모두 작동 할 수 있으며 선택한 옵션은 필요에 따라 다릅니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관