1

My app uses NSInputStream like below:

inputStream.delegate = self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [readStream open];

and delegate:

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent

It works fine, but all other requests that i do, it queued until first is finished. I can do one per time and there is no way to do multiple concurrent requests.

There is a solution ? Thank you

This solution not work for me : https://stackoverflow.com/a/15346292/1376961

UPDATE: Was my server can't handle multiple connections from the same source.

Community
  • 1
  • 1
Scinfu
  • 1,081
  • 13
  • 18

3 Answers3

2

You will need to create your streams in separate threads to enable them to work simultaneously. I assume you have a method that sets up the inputStream you referred to:

- (void)openStreamInNewThread {
    [NSThread detachNewThreadSelector:@selector(openStream) toTarget:self withObject:nil];
}

- (void)openStream {
    NSInputStream *inputStream;

    // stream  setup

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
                   forMode:NSRunLoopCommonModes];
}

Note that [NSRunLoop currentRunLoop] will return the runloop of the current thread. So you have the newly created stream running in a separate thread loading data simultaneously with other streams in their own threads.

Julian F. Weinert
  • 7,474
  • 7
  • 59
  • 107
  • What exactly does not work? Aren't delegate methods called ar all or only the ones providing data? Are you trying to connect multiple times to the same address and port? – Julian F. Weinert Nov 08 '15 at 15:31
  • only one operation work per time , when 1 finish the second start . I want all NSInputStream download , and yes , the same port and the same host but not the same ftp file/url – Scinfu Nov 08 '15 at 16:28
  • Can you confirm your server can handle multiple connections from the same source? – Julian F. Weinert Nov 08 '15 at 16:46
  • With a desktop ftp client i can download multiple files , how can i check it? – Scinfu Nov 08 '15 at 16:50
  • Your desktop client probably uses active FTP which connects via different ports and also from the server to the client. Have a look at the FTP classes I and nkreipke released via github, you ahould find it via his user profile – Julian F. Weinert Nov 08 '15 at 17:40
1

You can try to schedule each stream in its own run loop. Below is a refined method from the mock class designed to unit-test my POSInputStreamLibrary:

static const NSTimeInterval kRunLoopCycleInterval = 0.01f;
static const uint64_t kDispatchDeltaNanoSec = 250000000;

- (POSRunLoopResult)launchNSRunLoopWithStream:(NSInputStream *)stream delegate:(id<NSStreamDelegate>)streamDelegate {
    stream.delegate = streamDelegate;
    __block BOOL breakRunLoop = NO;
    __block dispatch_semaphore_t doneSemaphore = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [stream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];
        if ([stream streamStatus] == NSStreamStatusNotOpen) {
            NSLog(@"%@: opening stream...", [NSThread currentThread]);
            [stream open];
        }
        while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:kRunLoopCycleInterval]] && !breakRunLoop)
        {}
        NSLog(@"%@: We are done!", [NSThread currentThread]);
        dispatch_semaphore_signal(doneSemaphore);
    });
    POSRunLoopResult result = dispatch_semaphore_wait(doneSemaphore, dispatch_time(DISPATCH_TIME_NOW, kDispatchDeltaNanoSec)) == 0 ? POSRunLoopResultDone : POSRunLoopResultTimeout;
    if (POSRunLoopResultTimeout == result) {
        breakRunLoop = YES;
        dispatch_semaphore_wait(doneSemaphore, DISPATCH_TIME_FOREVER);
    }
    return result;
}
Pavel Osipov
  • 2,067
  • 1
  • 19
  • 27
1

Each time I create a new NSInputStream, I add it to a block object, and then store the block object in an NSMutableArray.

I posted code that streams video from one iOS to another:

https://app.box.com/s/94dcm9qjk8giuar08305qspdbe0pc784

Build this app with Xcode 11; run it on two iOS 11 devices.

Touch the Camera icon on one of the two devices to start streaming live video.

If you don't have two devices, you can run the app in a simulator; however, stream from the real device only (the camera is not available on the simulator).

James Bush
  • 1,485
  • 14
  • 19