Post

Replies

Boosts

Views

Activity

Combine. Is it possible to revert back effect of IgnoreOutput publisher?
I have a publisher with the following signature. AnyPublisher<Never, Error> As I understand it correctly, it is impossible to change its output to something like Void to just catch this output. Actually, I want to call flatMap on this publisher and change it, but flatMap will never been called because of Never output. So... Is it possible to revert ignoreOutput()?
0
0
558
Feb ’21
Is it possible to build event bus queue with combine publishers and subjects?
I have the following attempt. The main idea is to .receive(on: queue) operator with private queue However, it doesn't work as expected. Is it possible to build event bus queue with combine publishers and subjects? . swift class Work {     var cancellable: AnyCancellable?     var cancellable2: AnyCancellable?     typealias Input = Int     private var inputSubject: PassthroughSubjectInput, Never = .init()     private var inputPublisher: AnyPublisherInput, Never     init() {         let queue: DispatchQueue = .init(label: "com.abc.abc")         self.inputPublisher = self.inputSubject.receive(on: queue).eraseToAnyPublisher()         self.inputSubject     }     func handle(_ input: Input) {         self.inputSubject.send(input)     }     func work() {         let numbers: [Int] = Array(1...10)         self.cancellable2 = self.inputPublisher.sink { (value) in             let count: Int = .random(in: 3...5)             sleep(UInt32(count))             print(value)         }         self.cancellable = numbers.publisher.receive(on: DispatchQueue.global()).sink { [weak self] (value) in             self?.handle(value)         }     } }
0
0
861
Feb ’21
How to properly implement delay gap between operations for NSOperationQueue?
I have the following method in NSOperationQueue category:- (void)addOperation:(NSOperation *)op withDelayInNanoseconds:(int64_t)nanoseconds { int64_t delay = (self.operationCount * nanoseconds); int64_t timeInterval = (int64_t)(nanoseconds + delay); int64_t boundTimeInterval = timeInterval &amp;gt;= 0 ? timeInterval : 0; __weak typeof(self) weakSelf = self; NSLog(@"%@ addOperation: %@ intoQueue: %@ withOperationDelayInNanoseconds: %@ boundTimeInterval: %@. operationCount: %@", weakSelf.debugDescription, op, weakSelf.underlyingQueue, @(nanoseconds), @(boundTimeInterval), @(weakSelf.operationCount)); //uderlyingQueue could be nil. //maybe just add operation in queue? //https://github.com/Tricertops/GrandSwiftDispatch/issues/1 //maybe the best why is to remove such a queue :/ if (weakSelf.underlyingQueue == nil) { NSLog(@"%@ underlyingQueue is %@", weakSelf.debugDescription, weakSelf.underlyingQueue); } dispatch_queue_t queue = weakSelf.underlyingQueue ?: dispatch_queue_create("com.myproject.concurrency", NULL); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, boundTimeInterval), queue, ^{ [weakSelf addOperation:op]; }); }It may not work ( not sure how it works. )But in this code I encountered self.unerlyingQueue value nil due to documentation.So, I put adding operation in dispatch_after block and it is fires after delay.This example adds delay only before adding operation. It don't add delay gap between two operations with desired interval.Now I try to figure out how to do it.Subclass from NSOperation.@interface MyProjectDelayedOperation : NSOperation @property (assign, nonatomic, readwrite) NSInteger beforeDelayInSeconds; @property (assign, nonatomic, readwrite) NSInteger afterDelayInSeconds; @end @interface MyProjectDelayedOperation () @property (strong, readwrite) NSOperation *operation; @property (readwrite, getter=isCancelled) BOOL cancelled; @property (readwrite, getter=isExecuting) BOOL executing; @property (readwrite, getter=isFinished) BOOL finished; //@property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override 'asynchronous' below //@property (readonly, getter=isAsynchronous) BOOL asynchronous NS_AVAILABLE(10_8, 7_0); @property (readonly, getter=isReady) BOOL ready; @end static const void *observerContextIsCancelled; static const void *observerContextIsFinished; @implementation MyProjectDelayedOperation - (instancetype)initWithOperation:(NSOperation *)operation { if (self = [super init]) { self.operation = operation; [self.operation addObserver:self forKeyPath:@"isCancelled" options:0 context:observerContextIsCancelled]; [self.operation addObserver:self forKeyPath:@"isFinished" options:0 context:observerContextIsFinished]; } return self; } - (void)start { // wait before start for seconds. double delayInSeconds = self.beforeDelayInSeconds; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); __weak __typeof(self)weakSelf = self; dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [weakSelf willChangeValueForKey:@"isExecuting"]; weakSelf.executing = YES &amp;amp;&amp;amp; !weakSelf.cancelled; [weakSelf didChangeValueForKey:@"isExecuting"]; if (self.executing &amp;amp;&amp;amp; !self.cancelled) { [weakSelf.operation start]; } }); } // subscipt on operation values. - (void)cancel { [self willChangeValueForKey:@"isCancelled"]; self.cancelled = YES; [self didChangeValueForKey:@"isCancelled"]; if (!self.operation.cancelled) { [self.operation cancel]; } } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary&amp;lt;NSKeyValueChangeKey,id&amp;gt; *)change context:(void *)context { if ((object == self.operation) &amp;amp;&amp;amp; (context == observerContextIsCancelled)) { [self cancel]; } else if ((object == self.operation) &amp;amp;&amp;amp; (context == observerContextIsFinished)){ [self finished]; } } - (void)finished { // should wait for state "done" double delayInSeconds = self.afterDelayInSeconds; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); __weak __typeof(self)weakSelf = self; dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [weakSelf willChangeValueForKey:@"isExecuting"]; [weakSelf willChangeValueForKey:@"isFinished"]; weakSelf.executing = NO; weakSelf.finished = YES; [weakSelf didChangeValueForKey:@"isFinished"]; [weakSelf didChangeValueForKey:@"isExecuting"]; }); } @endIt wraps operation and adds intervals before start and after finish.It listens underlying operation events isCancelled and isFinished to react on them and to fire delayed operation finish.Not sure how to add before and after delays properly.Of course, this may work with queues maximum concurrent operations value equal one. ( Serial queue )
2
0
3.2k
May ’23
swift-log and osLog differences
Hey In my opinion osLog ( or Logging ) is an Apple Logging framework which provides logging facilities. And swift-log is Swift OpenSource framework which provides logging facitilies. And on Apple platforms Apple frameworks ( osLog ) are more conveinent and performant than Swift OpenSource frameworks. Am I right? So, a difference between these two frameworks is that swift-log provides an open source logging analogue for Swift.
1
0
119
Sep ’25