कैसे करने के लिए सीमा समवर्ती लाइव URLSessions के साथ गठबंधन?

0

सवाल

मैं एक बहुत कुछ है (~200) यूआरएल के लिए छवियों, और मैं डाउनलोड करने की जरूरत है प्रत्येक एक है, तो प्रक्रिया (आकार) यह है, तो कैश अद्यतन. बात है - मैं केवल चाहते हैं के लिए है पर अधिकतम 3 अनुरोधों को एक ही बार में, और के बाद से छवियों भारी रहे हैं, मैं भी नहीं करना चाहते हैं प्रतिक्रियाओं का एक बहुत "फांसी" प्रतीक्षा करने के लिए संसाधित किया जा सकता (और स्मृति...).

TLDR मैं कॉल करना चाहते हैं अगले (4) नेटवर्क अनुरोध के बाद ही receiveValue में sink कहा जाता है पर एक पहले 3 अनुरोधों... (यानी नेटवर्क के बाद प्रतिक्रिया और प्रसंस्करण कर रहे हैं दोनों के...).

इस प्रवाह का काम है, और यह होगा पकड़ पर प्रतीक्षा करने के लिए url नहीं है और फर्श पर उन्हें ड्रॉप?

यह भी क्या मैं की जरूरत है कि buffer() कॉल? मैं का उपयोग करें यह देखने के बाद इस सवाल का जवाब: https://stackoverflow.com/a/67011837/2242359

wayTooManyURLsToHandleAtOnce // this is a `[URL]`
    .publisher
    .buffer(size: .max, prefetch: .byRequest, whenFull: .dropNewest) // NEEDED?
    .flatMap(maxPublishers: .max(3)) { url in
       URLSession.shared
           .dataTaskPublisher(for: url)
           .map { (data: Data, _) -> Picture in
               Picture(from: data)
           }
    }
    .tryCompactMap {
        resizeImage(picture: $0) // takes a while and might fail
    }
    .receive(on: DispatchQueue.main)
    .sink { completion
        // handling completion... 
    } receiveValue: { resizedImage
        self.cache.append(resizedImage)
    }
    .store(...)
combine swift urlsession
2021-11-23 22:14:45
1

सबसे अच्छा जवाब

0

मैं प्रयोग करेंगे एक विषय है. यह नहीं है एक इष्टतम समाधान है, लेकिन यह लग रहा है काम करने की और शायद अन्य विचारों को ट्रिगर किया जाएगा

var cancellable: AnyCancellable?

var urls: [String] = (0...6).map { _ in "http://httpbin.org/delay/" + String((0...2).randomElement()!) }

var subject: PassthroughSubject<[String], Never> = .init()

let maxConcurrentRequests = 3

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    print(urls)
    
    cancellable = subject
        .flatMap({ urls -> AnyPublisher<[URLSession.DataTaskPublisher.Output], URLError> in
            let requests = urls.map { URLSession.shared.dataTaskPublisher(for: URL.init(string: $0)!) }
            return Publishers.MergeMany(requests)
                .collect().eraseToAnyPublisher()
        })
        .print()
        .sink(receiveCompletion: { completion in
            print(completion)
        }, receiveValue: { value in
            print(value)
            if self.urls.count <= self.maxConcurrentRequests {
                self.urls.removeAll()
                self.subject.send(completion: .finished)
            } else {
                self.urls.removeLast(self.maxConcurrentRequests)
                self.subject.send(self.urls.suffix(self.maxConcurrentRequests))
            }
        })
    
    subject.send(urls.suffix(maxConcurrentRequests))
}
2021-11-24 11:30:11

नहीं बुला self.subject.send(completion: .finished) सिंक पर अंत में मेरी सदस्यता हमेशा के लिए? (यानी की उपेक्षा कर भविष्य के मूल्यों उत्सर्जित)
Aviel Gross

@AvielGross हाँ, यह करता है । मैं समझ गया कि अपने संग्रह का url को बनाया एक बार देखने के प्रति नियंत्रक वर्तमान / खारिज. अगर इसकी नहीं सच तो नहीं भेज "."समाप्त हो गया, लेकिन आप एक ट्रिगर की तरह didSet पर यूआरएल सरणी या किसी अन्य के लिए relaunch के साथ विषय.भेजने के बाद खाली सरणी और refilling ।
Blazej SLEBODA

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................