Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When doing manual CFStream based connections on a separate thread (for custom things like bandwidth monitoring and throttling), I use a combination of CFReadStreamScheduleWithRunLoop, CFRunLoopRunInMode and CFReadStreamSetClient. Basically I run for 0.25 seconds and then check stream status. The client callback also gets notified on its own as well. This allows me to periodically check read status and do some custom behavior but rely mostly on (stream) events.</p> <pre><code>static const CFOptionFlags kMyNetworkEvents = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventEndEncountered | kCFStreamEventErrorOccurred; static void MyStreamCallBack(CFReadStreamRef readStream, CFStreamEventType type, void *clientCallBackInfo) { [(id)clientCallBackInfo _handleNetworkEvent:type]; } - (void)connect { ... CFStreamClientContext streamContext = {0, self, NULL, NULL, NULL}; BOOL success = CFReadStreamSetClient(readStream_, kMyNetworkEvents, MyStreamCallBack, &amp;streamContext); CFReadStreamScheduleWithRunLoop(readStream_, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); if (!CFReadStreamOpen(readStream_)) { // Notify error } while(!cancelled_ &amp;&amp; !finished_) { SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, NO); if (result == kCFRunLoopRunStopped || result == kCFRunLoopRunFinished) { break; } if (([NSDate timeIntervalSinceReferenceDate] - lastRead_) &gt; MyConnectionTimeout) { // Call timed out break; } // Also handle stream status CFStreamStatus status = CFReadStreamGetStatus(readStream_); if (![self _handleStreamStatus:status]) break; } CFRunLoopStop(CFRunLoopGetCurrent()); CFReadStreamSetClient(readStream_, 0, NULL, NULL); CFReadStreamUnscheduleFromRunLoop(readStream_, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); CFReadStreamClose(readStream_); } - (void)_handleNetworkEvent:(CFStreamEventType)type { switch(type) { case kCFStreamEventOpenCompleted: // Notify connected break; case kCFStreamEventHasBytesAvailable: [self _handleBytes]; break; case kCFStreamEventErrorOccurred: [self _handleError]; break; case kCFStreamEventEndEncountered: [self _handleBytes]; [self _handleEnd]; break; default: Debug(@"Received unexpected CFStream event (%d)", type); break; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload