<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 3, 2015, at 2:15 PM, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>&gt; wrote:</div><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 3, 2015, at 12:32 PM, Dan Stenmark &lt;<a href="mailto:daniel.j.stenmark@gmail.com" class="">daniel.j.stenmark@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">There’s a some of debate in the community regarding best practice for asynchronous completion callbacks. &nbsp;These practices include:<div class=""><br class=""></div><div class="">- Single Block w/ Mutually Exclusive Result and Error Objects (the current standard convention in Cocoa, though originally designed with Objective-C in mind)</div><div class="">- Double Block (one for success, one for failure)</div><div class="">- Swift Enum w/ Associated Objects (as described here:&nbsp;<a href="http://www.developerdave.co.uk/2015/09/better-completion-handlers-in-swift/" class="">http://www.developerdave.co.uk/2015/09/better-completion-handlers-in-swift/</a>)</div><div class=""><br class=""></div><div class="">Even prior to Swift, Apple’s code guidelines never explicitly addressed this topic. &nbsp;Going forward into the brave new world of Swift, are there going to be new preferred API design guidelines for this?</div></div></div></blockquote><br class=""></div><div class="">This is a great point, and there are a number of other issues related to callbacks/closure arguments that would benefit from guidelines. For example, I've seen the “Double Block” case where the second block ends up being a trailing closure, which makes for non-intuitive uses.</div></div></div></blockquote><br class=""></div><div><div>Hi Dan!</div><div><br class=""></div><div>I think guidelines in this area would be great.<br class=""></div><div><br class=""></div><div>Here are the tradeoffs I think we have for each approach:</div><div><br class=""></div><div><div class="">1) The single block approach means you’d code against an optional result and an optional error, making it easy to write invalid code (see example in #2). With the single block you can use trailing closure syntax coherently. I think most ObjC APIs use this approach since it works well in ObjC.<br class=""><br class=""></div><div class="">2) As Doug mentioned, the double block can be inconvenient / awkward but it does produce more correct code.&nbsp;</div><div class=""><b class=""><br class=""></b></div><div class=""><b class="">Doug</b>: maybe we can limit using trailing closures from being used if the 2nd to last parameter is also a closure? That would eliminate some confusion at the call site.</div><div class=""><br class=""></div><div class="">Some&nbsp;ObjC&nbsp;APIs use this approach. One positive aspect of the double-block approach is that it always produces code that’s less indented than the single block approach. e.g.</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp;/*</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Single block.</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Trailing closure syntax works well.</div><div class="">&nbsp; &nbsp; &nbsp;*/</div><div class="">&nbsp; &nbsp; &nbsp;request.fetch { result, error in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // More indented code since we need to use guard or if let.</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; guard let result = result else {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Need to force unwrap `error`.</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;handleFetchError(error!)&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; use(result)</div><div class="">&nbsp; &nbsp; &nbsp;}</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; &nbsp;/*</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Double block.</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Trailing closure syntax is awkward here.</div><div class="">&nbsp; &nbsp; &nbsp;*/</div><div class="">&nbsp; &nbsp; &nbsp;request.fetch(withCompletionHandler: { result in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; use(result) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div><div class="">&nbsp; &nbsp; &nbsp;}, errorHandler: { error in</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Don’t need to force unwrap `error`.</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handleFetchError(error)&nbsp;</div><div class="">&nbsp; &nbsp; &nbsp;})</div><div class=""><br class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">3) Enums with associated values are conceptually nice, but unless we have a Result&lt;&gt; or an Either&lt;&gt; in the Standard Library I think most people will write one-off enums for each set of methods that return a specific kind of result + error. That adds an unnecessary conceptual burden since you need to know the type of of the value that’s passed to each callback. Also, we don’t have any primarily ObjC&nbsp;APIs that use this approach yet. It would also suffer from the same indentation problem as #1 but without the “invalid code” problem. If we go this route I think we’d want to map the async error&nbsp;ObjC&nbsp;APIs to use this approach similar to what we do with non-async error handling.</div><div class=""><br class=""></div><div class="">Looking at the tradeoffs I think I prefer #2 if we could limit the ability to use a trailing closure for the last parameter. I’d want to look at more code with the change though. We should also consider whether we should map the single block APIs in&nbsp;ObjC&nbsp;into double block APIs. What do you think?</div><div class=""><br class=""></div><div class="">Also, with any of these approaches there’s also the question of whether we pass ErrorType, NSError, or the specific error type.</div></div></div></div></div><div><br class=""></div><div>- Alex</div><div class=""><br class=""></div></div><br class=""></body></html>