GitHub user kdubb opened a pull request: https://github.com/apache/thrift/pull/539
Thrift 2905 & - Modern Objective-C & Swift compatibility. This pull request is really just to start a conversation about how to move forward with the changes I've made to the Thrift Cocoa library and generator. The nature of the changes are that they are big & a bit destructive. Unfortunately there wasn't much getting around that. Hopefully working with the community we can agree on the best way to integrate these changes. Maybe just as another "language" binding instead of replacing the current "cocoa". ## Goals ## * Modernize generated code * Increase asynchronous support (both blocks and promises) * Remove use of deprecated classes & paradigms (e.g NSException, NSURLSession) * Greater Swift interoperability ## Major Changes ## * Use NSError based error & exception handling * Optionally generate PromiseKit methods in the asynchronous clients * Change asynchronous clients to be fully multi-thread safe * Added THTTPSessionTransport, asynchronous HTTP transport that works with NSURLSession * Use NS_ENUM enumerations (with standard format) * Struct fields & their "set" flags now use properties exclusively * Removed instance variables from public headers * Remove retain/release stubs * Remove all deallocs # Why? # We made some very large changes. Here's why... ## NSException to NSError ## The use of NSException has been very problematic for us. Aside from the direction of Apple, which is to use exceptions for "fatal errors" only, it comes with a host of issues. First, Clang still produces incorrect code in many cases when using exceptions. Take this code for example... ```objective-c executeBlockAndReturnValue(^{ @try { return value; } @catch(NSException *e) { } // should be a return statement on this branch, Clang produces no error/warning }); ``` Clang should produce an error but doesn't. This is only a nuisance though, much worse are the ARC failures we've found when catching exceptions up the stack. Secondly, Swift has no support for exceptions (and with Swift 2 we've seen it won't ever use NSException). It's for these reasons we changed the the Cocoa library to use NSError, all of the generated (synchronous) methods now follow the Apple guidelines and return a BOOL or object pointer with a last error parameter of type NSError**; return values of NO or nil mean the error parameter is populated and the call failed (or and exception was thrown from the server). These changes have been made throughout the generated and library code. *Synchronous Client Method Mapping* Only synchronous method mappings are affected. The asynchronous methods have ways to report errors out-of-band that don't require mapping types. * Methods returning basic types are mapped to NSNumber/NSValue - nil reports call failure/exception * Methods returning VOID are mapped to return BOOL - NO reports call failure/exception * Methods returning Struct/String/Binary return the object value as normal - nil reports call failure/exception ### NSError & Swift 2 ### These changes conveniently take the form of Swift 2's error handling system. This means that protocols and transports can be used from and written in Swift and will be compatible with the current & future directions of Swift. ## ARC Only ## ARC is here to stay; Apple deprecated everything else a few years ago. All code related to maintaining backwards compatibly with non-ARC mode has been removed. ## Mutl-Threaded Asynchronous Transports ## The current implementations means that clients cannot be used in different threads. This means the user is left to synchronize access to them or, as in our case, build a client per thread to ensure parallelism. Our changes have reengineered the way asynchronous works. Now, asynchronous clients accept only protocol and async-transport factories. Each call allocates a new transport and protocol binds them before use. This provides the best options for parallelism with a fairly small overhead. A note on performance... the alternative approaches, which we used in the past, required thread local storage inside the transport which meant an NSDictionary lookup (i.e. threadDictionary) for each read/write/flush. The new approach only requires 2 simple object allocations. Much improved. ## NSURLSession (NSURLConnection is now deprecated) ## The new THTTPSessionTransport replaces the old THTTPClient. It's both asynchronous and uses the new NSURLSession classes for conformance in the new iOS/OSX versions. You can merge this pull request into a Git repository by running: $ git pull https://github.com/reTXT/thrift THRIFT-2905 Alternatively you can review and apply these changes as the patch at: https://github.com/apache/thrift/pull/539.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #539 ---- commit a7e2544d55e366f1259afd508c3646cb64df716a Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-03T02:43:27Z Modernized Cocoa ⢠Use NSError based error & exception handling ⢠Use NS_ENUM enumerations (with standard format) ⢠nullable & nonnull attributes for parameters ⢠Swift interoperability (nullability, enums & error handling) ⢠Removed instance variables from public header ⢠Remove retain/release stubs ⢠Remove all deallocs commit e73f7b644cde831ed14729c0962a51d0476de788 Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-03T18:32:19Z Add optional support for PromiseKit to async clients commit 1220b0a7d60d24680813dc214cd5464ebe0989b4 Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-03T20:17:00Z Fix analyzer surfaced issues with SSL socket commit 0b91a7761c74e97783093885a92814f50aa03566 Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-03T20:18:31Z Protocols wrap transport errors with more information The current message name & source file/line information is added to the protocol error that wraps the transport error. commit 9925c463fd40466a8f2974869af01048767938a8 Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-03T22:58:47Z Make async transports & clients mutl-thread safe commit 467efe8878357c48f3b2080c82a28d0bf86c7bd8 Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-03T23:32:34Z Rename transport "Clients" to transports. Client is the terminology for the top level object already. commit fcc3ae3a47d0cbf4774b0ac8b7f543fe144db5cf Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-03T23:32:50Z Fix async client init method commit cb0f4325bef01ee9282a0055f5a29c415864fb9c Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-04T01:11:33Z Fix setter name generation commit 5ffe3478c01ee70e7489be196bc280aefe8ab5b0 Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-04T01:11:55Z Simplify NSError reading logic commit 9a2bf0416d657ad643819aafa6943c1c8cc29ebc Author: Kevin Wooten <ke...@wooten.com> Date: 2015-07-04T01:12:51Z Fix HTTP sessoin transport's response data loading ---- --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---