본문 바로가기

개발

Combine Publisher - Future

728x90

Combine에서 와 는 모두 데이터 스트림을 처리하는 역할을 하지만 서로 다른 목적을 갖습니다.

발행자:

  • 시간이 지남에 따라 방출되는 값이나 이벤트의 소스를 나타냅니다.
  • 여러 개의 값을 순차적으로 내보낼 수 있습니다.
  • 예: , , . Just PassthroughSubject CurrentValueSubject

Future:

  • 결국 값이나 오류를 생성하는 단일 비동기 작업을 나타냅니다.
  • 단일 값을 방출한 후 완료됩니다.
  • 비동기 작업을 위한 특수한 유형의 게시자로 볼 수 있습니다.
  • 종종 비동기 작업을 수행하는 함수나 클로저와 함께 사용됩니다.

주요 차이점을 요약한 표는 다음과 같습니다.

특징 발행자 미래
방출된 다중 (순차적) 단일
완성 모든 값이 방출된 신호 완료 단일 또는 오류가 발생한 신호 완료
사용 사례 일반 데이터 스트림, UI 업데이트 비동기 작업, 네트워크 요청, 파일 I/O

Combine과 함께 Future 사용:

  1. Future 생성: 비동기 작업을 수행하고 객체를 반환하는 함수 또는 클로저를 정의합니다 Future. 이 future는 작업의 최종 결과를 캡슐화합니다.
  2. 미래에 구독: 객체를 게시자로 사용 하고 다른 게시자와 마찬가지로 구독합니다. 구독자의 클로저 내에서 완료(성공 또는 실패)와 수신된 값(성공한 경우)을 처리합니다.

다음은 그 예입니다.

import Combine



func fetchDataFromNetwork() -> Future<String, Error> {

  // Simulate asynchronous network request

  return Future { promise in

    DispatchQueue.global().asyncAfter(deadline: .now() + 2) {

      promise(.success("Fetched data!"))

    }

  }

}



// Subscribe to the Future

fetchDataFromNetwork()

  .sink(receiveCompletion: { completion in

    if case .failure(let error) = completion {

      print("Error fetching data: \(error)")

    }

  }, receiveValue: { value in

    print("Fetched data: \(value)")

  })

 

이 예에서:

  • fetchDataFromNetwork(가져온 데이터를 나타내는) Future유형의 a를 반환하는 함수를 정의합니다 .StringError
  • 미래는 지연을 통해 네트워크 요청을 시뮬레이션합니다.
  • 우리는 미래를 구독하고 구독자 마감 내에서 완료와 수신된 가치를 처리합니다.

키 포인트:

  • Combine은 .을 사용하여 비동기 작업과 잘 통합됩니다.
  • Future데이터 스트림 내에서 비동기 작업의 결과(성공 또는 실패)를 처리하는 체계적인 방법을 제공합니다.
  • 복잡한 비동기 워크플로를 만드는 것과 같은 연산자를 사용하여 여러 퓨처를 연결할 수 있습니다 flatMap.

게시자와 퓨처의 차이점을 이해하면 Combine 애플리케이션에서 비동기 작업과 데이터 흐름을 효과적으로 관리할 있습니다.

 

Future다음은 Combine에서 및 를 함께 사용하여 비동기 작업을 수행하고 결과를 처리하는 방법에 대한 몇 가지 예입니다 .

 

1. URL에서 데이터 가져오기:

import Combine



func fetchDataFromURL(_ url: URL) -> Future<String, Error> {

  // Simulate asynchronous network request

  return Future { promise in

    URLSession.shared.dataTask(with: url) { (data, response, error) in

      if let error = error {

        promise(.failure(error))

        return

      }



      guard let data = data else {

        promise(.failure(URLError(.cannotLoadPage)))

        return

      }



      let stringData = String(decoding: data, as: UTF8.self)

      promise(.success(stringData))

    }.resume()

  }

}



let url = URL(string: "https://www.example.com")!



fetchDataFromURL(url)

  .sink(receiveCompletion: { completion in

    if case .failure(let error) = completion {

      print("Error fetching data: \(error)")

    }

  }, receiveValue: { value in

    print("Fetched data: \(value)")

  })

 

2. URL에서 이미지 로딩:

import Combine

import SwiftUI



func loadImageFromURL(_ url: URL) -> Future<UIImage?, Error> {

  // Simulate asynchronous image loading

  return Future { promise in

    URLSession.shared.dataTask(with: url) { (data, response, error) in

      if let error = error {

        promise(.failure(error))

        return

      }



      guard let data = data else {

        promise(.failure(URLError(.cannotLoadPage)))

        return

      }



      let image = UIImage(data: data)

      promise(.success(image))

    }.resume()

  }

}



let url = URL(string: "https://www.example.com/image.jpg")!



loadImageFromURL(url)

  .sink(receiveCompletion: { completion in

    if case .failure(let error) = completion {

      print("Error loading image: \(error)")

    }

  }, receiveValue: { image in

    if let image = image {

      // Display the image in SwiftUI view

      Image(uiImage: image)

        .resizable()

        .scaledToFit()

    } else {

      // Handle the case where no image was loaded

    }

  })

 

3. Delaying and Transforming a Value:

 

import Combine



func delayedValue(_ value: Int, delay: Double) -> Future<Int, Never> {

  // Simulate asynchronous delay

  return Future { promise in

    DispatchQueue.global().asyncAfter(deadline: .now() + delay) {

      promise(.success(value))

    }

  }

}



// Delay and transform the value

delayedValue(10, delay: 2)

  .map { $0 * 2 } // Multiply the value by 2

  .sink(receiveCompletion: { _ in }, receiveValue: { value in

    print("Delayed and transformed value: \(value)")

  })

설명:

  • 각 예제에서 비동기 작업(네트워크 요청, 이미지 로딩 등 )을 수행하고 Future. 을 반환하는 함수를 정의합니다.
  • 이는 Future작업의 최종 결과( 성공 값 또는 오류)를 캡슐화합니다.
  • Future우리는 메서드 를 사용하여 구독 sink하고 완료(성공 또는 실패)와 수신된 값(성공 시)을 처리합니다.
  • Future이 예제 에서는 Combine 연산자를 사용 하여 수신된 값을 변환하는 방법을 보여줍니다 .map

키 포인트:

  • FutureCombine 데이터 스트림 내에서 비동기 작업을 처리하는 강력한 도구입니다.
  • Future게시자와 운영자와 협력하여 복잡한 비동기 워크플로를 만들고 그 결과를 효과적으로 관리할 수 있습니다.
  • 견고하고 반응성이 뛰어난 애플리케이션을 보장하려면 오류를 적절히 처리하는 것이 중요합니다.

'개발' 카테고리의 다른 글

Combine Publisher - Empty  (0) 2024.07.08
Combine Publisher - Deferred  (0) 2024.07.08
Combine Publisher - Just  (0) 2024.07.08
Publisher & Subscriber - Combine  (0) 2024.07.08
Combine Publishers  (0) 2024.07.08