With the following code and a bunch of other variations I've tried, I always get an unauthorized error. I'm using TwitterKit 3.0 using CocoaPods. I've got my plist setup, my twitter app configured, and code like this:
// In didFinishLaunchingWithOptions
Twitter.sharedInstance().start(withConsumerKey:"XX", consumerSecret:"YYY")
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
{
    return Twitter.sharedInstance().application(app, open: url, options: options)
}
// In response to a click
Twitter.sharedInstance().logIn { session, error in
    if session != nil { // Log in succeeded
        let composer = TWTRComposer()
        composer.setText(tweetText)
        composer.show(from: self.navigationController!) { result in
            if (result == .done) {
                print("Successfully composed Tweet")
            } else {
                print("Cancelled composing")
            }
        }
    }
}
"Did encounter error sending Tweet: Error Domain=TWTRNetworkingErrorDomain Code=-1011 "Request failed: unauthorized (401)" UserInfo={NSLocalizedFailureReason=, TWTRNetworkingStatusCode=401, NSErrorFailingURLKey=https://api.twitter.com/1.1/statuses/update.json, NSLocalizedDescription=Request failed: unauthorized (401)"
 
     
     
     
     
    