57249


teratailでも質問した内容ですが、こちらでも質問させていただきます。

アプリ内でツイート、ダイレクトメッセージの送信、タイムラインの取得を行うOSアプリケーションを開発しています。その際、ユーザを[Swifter](https://github.com/mattdonnelly/Swifter)でOAuthを介してauthorizeする際に、SFSafatiViewController内でtwitter認証したのち、画面が閉じた途端にエラーが出てしまい認証ができません。

エラーメッセージと該当箇所のコードおよびライブラリなどのバージョンは以下の通りです。  
`LogInTwitterViewController.swift`内の`LogInTwitter()`中の`authorize()`を除いてtwitter
developerから取得したアクセストークンを用いたところ、テストツイートは作動したため(ただし認証画面は表示されずデベロッパ登録したアカウントからツイートされる)、おそらく`authorize(
)`の使い方に何かしら問題があるのではないかと思っています。  
iOS開発は初心者なので破茶滅茶な質問をしているかもしれませんが、ご寛恕願います。

**エラーメッセージ** ("Failed In Logging In"はエラー箇所の特定のため表示させています)

[code]

    Failed In Logging In
    SwifterError(message: "Bad OAuth response received from server", kind: badOAuthResponse)
    
[/code]

**Swifter関連箇所のソースコード**

LoggingInTwitter.swift

[code]

    import Foundation
    import SwifteriOS
    
    public var isLoggedInTwitter = false
    
    public let swifter = Swifter(consumerKey: "コンシューマキー", consumerSecret: "コンシューマシークレット")
    
[/code]

LogInTwitterViewController.swift

[code]

    import UIKit
    import SafariServices
    import SwifteriOS
    
    class LoggingInTwitterViewController: UIViewController, SFSafariViewControllerDelegate {
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
            // Do any additional setup after loading the view.
            if(isLoggedInTwitter){
                self.performSegue(withIdentifier: "SegueFromStartingViewToHomeView", sender: nil)
            }
            else{
              self.LogInTwitter()
            }
        }
    
    func LogInTwitter(){
            swifter.authorize(
                withCallback: URL(string:"app-アプリ名://")!,
                presentingFrom: self,
                success: { accessToken, response in
                    guard let accessToken = accessToken else {
                        return
                    }
                    let oAuthToken = accessToken.key
                    let secret = accessToken.secret
                    UserDefaults.standard.set(oAuthToken, forKey: "oAuthToken")
                    UserDefaults.standard.set(secret, forKey: "secret")
    　　　　　　　　　 isLoggedInTwitter = true
            }, failure: { error in
                print("Failed In Logging In")
                print(error)
            })
            guard let oAuthToken = UserDefaults.standard.string(forKey: "oAuthToken") else { return }
            guard let secret = UserDefaults.standard.string(forKey: "secret") else { return }
    
            //認証情報の格納
            let Sw_Token = Credential.OAuthAccessToken(key: oAuthToken, secret: secret)
            let Sw_credential = Credential(accessToken: Sw_Token)
            swifter.client.credential = Sw_credential
    　　　　　//テストツイート
            swifter.postTweet(status: "This is test tweet")
    
    　　　　 //
            self.performSegue(withIdentifier: "SegueFromStartingViewToHomeView", sender: nil)
        }
    
    
[/code]

AppDelegate.swift

[code]

    import UIKit
    import CoreData
    import SwifteriOS
    import Firebase
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            FirebaseApp.configure()
            return true
        }
    
        func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
            Swifter.handleOpenURL(URL(string:"app-アプリ名://")!)
            return true
        }
    
        func applicationWillResignActive(_ application: UIApplication) {
    
        }
    
        func applicationDidEnterBackground(_ application: UIApplication) {
    
        }
    
        func applicationWillEnterForeground(_ application: UIApplication) {
    
        }
    
        func applicationDidBecomeActive(_ application: UIApplication) {
    
        }
    
        func applicationWillTerminate(_ application: UIApplication) {
            self.saveContext()
        }
    
        lazy var persistentContainer: NSPersistentContainer = {
    
            let container = NSPersistentContainer(name: "アプリ名")
            container.loadPersistentStores(completionHandler: { (storeDescription, error) in
                if let error = error as NSError? {
                    fatalError("Unresolved error \(error), \(error.userInfo)")
                }
            })
            return container
        }()
    
        func saveContext () {
            let context = persistentContainer.viewContext
            if context.hasChanges {
                do {
                    try context.save()
                } catch {
                    let nserror = error as NSError
                    fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
                }
            }
        }
    
    }
    
[/code]

**実行環境**  
Xcode 10.3  
Swift 5  
Swifter-2.2.2  
CocoaPod 1.7.5


CC BY-SA 4.0
2019-08-06T03:43:03.717
57195
2019-08-08T09:16:58.323
2019-08-06T05:51:12.800
3060
35375
question
swift oauth
SwifterでユーザをAuthorizeできない


Swiftの文法は全く知りませんが、GitHubの多くの人の実装を見ると、

[code]

    withCallback: URL(string:"app-アプリ名://")!,
    
[/code]

ではなく、次のようにしていますね。

[code]

    withCallback: URL(string: "アプリ名://success")!, 
    
[/code]


CC BY-SA 4.0
2019-08-08T09:16:58.323
57249
2019-08-08T09:16:58.323
21092
57195
answer