<div dir="ltr">Quinn, Jens, thanks for pointing me at the NSStream classes. For some reason, I discarded NSStream quickly after seeing the first paragraph of <a href="https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Streams/Articles/WritingOutputStreams.html">Apple's documentation on output streams</a> listing 5 relatively complex steps — without realizing that this API also has a synchronous interface.<div><br></div><div>Obviously, the NSStream API is too low level and thus difficult to use. Therefore, I would also like to see Apple build a great IO streaming API for Swift. I've implemented Quinn's example using NSInputStream and Swift's Generator design pattern. Except for mapping NSInputStream to a generator — which is really messy — everything else is straightforward and much more extensible and scalable than the standard Foundation approach. The code is below.</div><div><br></div><div>== Matthias</div><div><br></div><div>See <a href="https://gist.github.com/objecthub/ada1f852924b2c253653d6949fd3555d">https://gist.github.com/objecthub/ada1f852924b2c253653d6949fd3555d</a><br></div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(39,42,216)">class</span><span style=""> ByteGenerator: </span><span style="color:rgb(112,61,170)">GeneratorType</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">typealias</span><span style=""> Element = </span><span style="color:rgb(112,61,170)">UInt8</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(39,42,216)">let</span><span style="color:rgb(0,0,0)"> input: </span><span style="">NSInputStream</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> buffer: [</span><span style="color:rgb(112,61,170)">UInt8</span><span style="">]</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> index: </span><span style="color:rgb(112,61,170)">Int</span><span style=""> = </span><span style="color:rgb(196,49,198)">0</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> eof: </span><span style="color:rgb(112,61,170)">Bool</span><span style=""> = </span><span style="color:rgb(39,42,216)">true</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">init</span><span style="">?(path: </span><span style="color:rgb(112,61,170)">String</span><span style="">, capacity: </span><span style="color:rgb(112,61,170)">Int</span><span style=""> = </span><span style="color:rgb(196,49,198)">1024</span><span style="">) {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">guard</span><span style=""> </span><span style="color:rgb(39,42,216)">let</span><span style=""> input = </span><span style="color:rgb(112,61,170)">NSInputStream</span><span style="">(fileAtPath: path) </span><span style="color:rgb(39,42,216)">else</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(39,42,216)"><span style="color:rgb(0,0,0)"> </span><span style="">return</span><span style="color:rgb(0,0,0)"> </span><span style="">nil</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">buffer</span><span style=""> = [</span><span style="color:rgb(112,61,170)">UInt8</span><span style="">](count: capacity, repeatedValue: </span><span style="color:rgb(196,49,198)">0</span><span style="">)</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> input.</span><span style="color:rgb(61,29,129)">open</span><span style="">()</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(39,42,216)">if</span><span style="color:rgb(0,0,0)"> input.</span><span style="">hasBytesAvailable</span><span style="color:rgb(0,0,0)"> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">eof</span><span style=""> = input.</span><span style="color:rgb(61,29,129)">read</span><span style="">(&</span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">buffer</span><span style="">, maxLength: </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">buffer</span><span style="">.</span><span style="color:rgb(112,61,170)">count</span><span style=""> * </span><span style="color:rgb(61,29,129)">sizeof</span><span style="">(</span><span style="color:rgb(112,61,170)">UInt8</span><span style="">)) <= </span><span style="color:rgb(196,49,198)">0</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">input</span><span style=""> = input</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(39,42,216)">deinit</span><span style="color:rgb(0,0,0)"> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(79,129,135)">input</span><span style="">.</span><span style="color:rgb(61,29,129)">close</span><span style="">()</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">func</span><span style=""> next() -> </span><span style="color:rgb(112,61,170)">UInt8</span><span style="">? {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(39,42,216)"><span style="color:rgb(0,0,0)"> </span><span style="">guard</span><span style="color:rgb(0,0,0)"> !</span><span style="">self</span><span style="color:rgb(0,0,0)">.</span><span style="color:rgb(79,129,135)">eof</span><span style="color:rgb(0,0,0)"> </span><span style="">else</span><span style="color:rgb(0,0,0)"> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(39,42,216)"><span style="color:rgb(0,0,0)"> </span><span style="">return</span><span style="color:rgb(0,0,0)"> </span><span style="">nil</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">if</span><span style=""> </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">index</span><span style=""> >= </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">buffer</span><span style="">.</span><span style="color:rgb(112,61,170)">count</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">index</span><span style=""> = </span><span style="color:rgb(196,49,198)">0</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(39,42,216)">self</span><span style="color:rgb(0,0,0)">.</span><span style="color:rgb(79,129,135)">eof</span><span style="color:rgb(0,0,0)"> = !</span><span style="color:rgb(79,129,135)">input</span><span style="color:rgb(0,0,0)">.</span><span style="">hasBytesAvailable</span><span style="color:rgb(0,0,0)"> ||</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(79,129,135)">input</span><span style="">.</span><span style="color:rgb(61,29,129)">read</span><span style="">(&</span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">buffer</span><span style="">, maxLength: </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">buffer</span><span style="">.</span><span style="color:rgb(112,61,170)">count</span><span style=""> * </span><span style="color:rgb(61,29,129)">sizeof</span><span style="">(</span><span style="color:rgb(112,61,170)">UInt8</span><span style="">)) <= </span><span style="color:rgb(196,49,198)">0</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(39,42,216)"><span style="color:rgb(0,0,0)"> </span><span style="">guard</span><span style="color:rgb(0,0,0)"> !</span><span style="">self</span><span style="color:rgb(0,0,0)">.</span><span style="color:rgb(79,129,135)">eof</span><span style="color:rgb(0,0,0)"> </span><span style="">else</span><span style="color:rgb(0,0,0)"> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">return</span><span style=""> </span><span style="color:rgb(39,42,216)">nil</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">index</span><span style=""> += </span><span style="color:rgb(196,49,198)">1</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(39,42,216)"><span style="color:rgb(0,0,0)"> </span><span style="">return</span><span style="color:rgb(0,0,0)"> </span><span style="">self</span><span style="color:rgb(0,0,0)">.</span><span style="color:rgb(79,129,135)">buffer</span><span style="color:rgb(0,0,0)">[</span><span style="">self</span><span style="color:rgb(0,0,0)">.</span><span style="color:rgb(79,129,135)">index</span><span style="color:rgb(0,0,0)"> - </span><span style="color:rgb(196,49,198)">1</span><span style="color:rgb(0,0,0)">]</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="">}</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span style=""></span><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(39,42,216)">struct</span><span style=""> CharacterGenerator<G: GeneratorType, U: UnicodeCodecType </span><span style="color:rgb(39,42,216)">where</span><span style=""> G.Element == U.CodeUnit>: </span><span style="color:rgb(112,61,170)">GeneratorType</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">typealias</span><span style=""> Element = </span><span style="color:rgb(112,61,170)">Character</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> source: </span><span style="color:rgb(79,129,135)">G</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> decoder: </span><span style="color:rgb(79,129,135)">U</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">mutating</span><span style=""> </span><span style="color:rgb(39,42,216)">func</span><span style=""> next() -> </span><span style="color:rgb(112,61,170)">Character</span><span style="">? {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">guard</span><span style=""> </span><span style="color:rgb(39,42,216)">case</span><span style=""> .</span><span style="color:rgb(61,29,129)">Result</span><span style="">(</span><span style="color:rgb(39,42,216)">let</span><span style=""> scalar) = </span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">decoder</span><span style="">.</span><span style="color:rgb(61,29,129)">decode</span><span style="">(&</span><span style="color:rgb(39,42,216)">self</span><span style="">.</span><span style="color:rgb(79,129,135)">source</span><span style="">) </span><span style="color:rgb(39,42,216)">else</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(39,42,216)"><span style="color:rgb(0,0,0)"> </span><span style="">return</span><span style="color:rgb(0,0,0)"> </span><span style="">nil</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">return</span><span style=""> </span><span style="color:rgb(112,61,170)">Character</span><span style="">(scalar)</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="">}</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span style=""></span><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(39,42,216)">struct</span><span style=""> LineGenerator<G: GeneratorType </span><span style="color:rgb(39,42,216)">where</span><span style=""> G.Element == Character>: </span><span style="color:rgb(112,61,170)">GeneratorType</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">typealias</span><span style=""> Element = </span><span style="color:rgb(112,61,170)">String</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> source: </span><span style="color:rgb(79,129,135)">G</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">mutating</span><span style=""> </span><span style="color:rgb(39,42,216)">func</span><span style=""> next() -> </span><span style="color:rgb(112,61,170)">String</span><span style="">? {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">guard</span><span style=""> </span><span style="color:rgb(39,42,216)">let</span><span style=""> fst = </span><span style="color:rgb(79,129,135)">source</span><span style="">.</span><span style="color:rgb(61,29,129)">next</span><span style="">() </span><span style="color:rgb(39,42,216)">else</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(39,42,216)"><span style="color:rgb(0,0,0)"> </span><span style="">return</span><span style="color:rgb(0,0,0)"> </span><span style="">nil</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">guard</span><span style=""> fst != </span><span style="color:rgb(196,49,198)">"\n"</span><span style=""> </span><span style="color:rgb(39,42,216)">else</span><span style=""> {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">return</span><span style=""> </span><span style="color:rgb(196,49,198)">""</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> line = </span><span style="color:rgb(112,61,170)">String</span><span style="">(fst)</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">while</span><span style=""> </span><span style="color:rgb(39,42,216)">let</span><span style=""> ch = </span><span style="color:rgb(79,129,135)">source</span><span style="">.</span><span style="color:rgb(61,29,129)">next</span><span style="">() {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">if</span><span style=""> (ch == </span><span style="color:rgb(196,49,198)">"\n"</span><span style="">) {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">return</span><span style=""> line</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> line.</span><span style="color:rgb(61,29,129)">append</span><span style="">(ch)</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">return</span><span style=""> line</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="">}</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span style=""></span><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(196,49,198)"><span style="color:rgb(39,42,216)">if</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(39,42,216)">let</span><span style="color:rgb(0,0,0)"> input = </span><span style="color:rgb(48,123,99)">ByteGenerator</span><span style="color:rgb(0,0,0)">(path: </span><span style="">"/Users/username/filename.txt"</span><span style="color:rgb(0,0,0)">) {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> generator = </span><span style="color:rgb(79,129,135)">LineGenerator</span><span style="">(source: </span><span style="color:rgb(79,129,135)">CharacterGenerator</span><span style="">(source: input, decoder: </span><span style="color:rgb(112,61,170)">UTF8</span><span style="">()))</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">var</span><span style=""> i = </span><span style="color:rgb(196,49,198)">0</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(39,42,216)">while</span><span style=""> </span><span style="color:rgb(39,42,216)">let</span><span style=""> line = generator.</span><span style="color:rgb(49,89,93)">next</span><span style="">() {</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> </span><span style="color:rgb(61,29,129)">print</span><span style="">(</span><span style="color:rgb(196,49,198)">"</span><span style="">\</span><span style="color:rgb(196,49,198)">(</span><span style="">i</span><span style="color:rgb(196,49,198)">): </span><span style="">\</span><span style="color:rgb(196,49,198)">(</span><span style="">line</span><span style="color:rgb(196,49,198)">)"</span><span style="">)</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> i += </span><span style="color:rgb(196,49,198)">1</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style=""> }</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="">}</span></p></div><div><span style=""><br></span></div><div><br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><font face="arial, helvetica, sans-serif"><br></font><table width="100%" bgcolor="#efefef" style="color:rgb(102,102,102);font-size:11px;padding:3px 8px;border-top-width:1px;border-top-style:solid;border-top-color:rgb(170,170,170);border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(170,170,170)"><tbody><tr><td align="left"><b style="color:rgb(119,119,119)"><font face="arial, helvetica, sans-serif">Matthias Zenger</font></b></td><td align="right"><a href="mailto:matthias@objecthub.net" style="text-decoration:none;color:rgb(102,102,102)" target="_blank"><font face="arial, helvetica, sans-serif">matthias@objecthub.net</font></a></td></tr></tbody></table></div><div><br></div></div></div></div>
<br><div class="gmail_quote">On Sun, Jun 5, 2016 at 8:36 PM, Jens Alfke <span dir="ltr"><<a href="mailto:jens@mooseyard.com" target="_blank">jens@mooseyard.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On Jun 4, 2016, at 6:25 PM, Matthias Zenger via swift-users <<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>> wrote:</div><br><div><span style="font-family:Alegreya-Regular;font-size:15px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">I wanted to use NSFileHandle (for a use case that requires streaming) and realized that this is an API that cannot really be used in Swift because it's based on Objective-C exceptions. </span></div></blockquote><div><br></div></span><div>You’re right, NSFileHandle is a very archaic class (kind of a coelacanth) and its I/O methods signal errors by throwing exceptions. It’s almost unique in that regard; in general Cocoa APIs are only supposed to throw exceptions for programmer errors like assertion failures.</div><br><blockquote type="cite"><div><span style="font-family:Alegreya-Regular;font-size:15px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">Are there any alternatives?</span><br></div></blockquote></div><br><div>NSStream.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>—Jens</div></font></span></div></blockquote></div><br></div>