質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

295閲覧

[swift]MVPモデルでSpotifyAPIを叩いてTableViewに表示する際、遷移ができない。

taro-ken

総合スコア0

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/03/07 07:08

MVPを学習中です。

SpotifyAPIを叩いてTableViewに表示するサンプルを作成しています。

【実現したいこと】
アクセストークンをリクエストして、返ってきたアクセストークンキーをUserDefaultsで保存後
TableViewの画面に遷移させてプレイリストを取得、表示したいのですが
画面に遷移ができません。

【ソースコード】
遷移はRouterクラスに全て任せています。

Router.swift

1import UIKit 2 3final class Router { 4 static let shared = Router() 5 private init() {} 6 7 private var window: UIWindow? 8 9 func showRoot(window: UIWindow) { 10 guard let vc = UIStoryboard.init(name: "Login", bundle: nil).instantiateInitialViewController() as? LoginViewController else { 11 return 12 } 13 //presenterとvc同士を繋ぎ合う 14 let presenter = MVPLoginPresenter(output: vc) 15 vc.inject(presenter: presenter) 16 17 let nav = UINavigationController(rootViewController: vc) 18 window.rootViewController = nav 19 window.makeKeyAndVisible() 20 self.window = window 21 } 22 23 func showList(from: UIViewController) { 24 guard let list = UIStoryboard.init(name: "List", bundle: nil).instantiateInitialViewController() as? ListViewController else { 25 return 26 } 27 //presenterとvc同士を繋ぎ合う 28 let presenter = MVPListPresenter(output: list) 29 list.inject(presenter: presenter) 30 show(from: from, to: list) 31 } 32 33 private func show(from: UIViewController, to: UIViewController, completion:(() -> Void)? = nil){ 34 if let nav = from.navigationController { 35 nav.pushViewController(to, animated: true) 36 completion?() 37 } else { 38 from.present(to, animated: true, completion: completion) 39 } 40 } 41}

AppDelegate.swift

1import UIKit 2 3@main 4class AppDelegate: UIResponder, UIApplicationDelegate { 5 6 var window: UIWindow? 7 private var mvpLoginPresenterinput: MVPLoginPresenterInput! 8 9 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 10   //初期画面立ち上げ 11 Router.shared.showRoot(window: UIWindow(frame: UIScreen.main.bounds)) 12 return true 13} 14 15 func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 16 17 guard let vc = UIStoryboard.init(name: "Login", bundle: nil).instantiateInitialViewController() as? LoginViewController else { 18 return true 19 } 20 //presenterとvc同士を繋ぎ合う 21 let presenter = MVPLoginPresenter(output: vc) 22 vc.inject(presenter: presenter) 23 vc.openURL(url: url) 24 return true 25 } 26 27}

MVPLoginPresenter.swift

1import Foundation 2 3 4protocol MVPLoginPresenterInput { 5 func open(url: URL) 6} 7 8 9protocol MVPLoginPresenterOutput: AnyObject { 10 func showList() 11 func openURL(url: URL) 12} 13 14final class MVPLoginPresenter { 15 16 private weak var output: MVPLoginPresenterOutput! 17 18 19 private var playListModel: [item] 20 21 init(output: MVPLoginPresenterOutput) { 22 self.output = output 23 self.playListModel = [] 24 } 25} 26 27extension MVPLoginPresenter: MVPLoginPresenterInput { 28 29 func open(url: URL) { 30 guard let queryItems = URLComponents(string: url.absoluteString)?.queryItems, 31 let code = queryItems.first(where: {$0.name == "code"})?.value, 32 let getState = queryItems.first(where: {$0.name == "state"})?.value, 33 getState == API.shared.stateStr 34 else { 35 return 36 } 37 38 // `code`を引数として渡して、トークンリクエストをする 39 API.shared.postAuthorizationCode(code: code) { [weak self] accessToken, error in 40 if let _error = error { 41 print(_error.localizedDescription) 42 return 43 } 44 guard let _accessToken = accessToken else { 45 return 46 } 47 // キーを保持 48 UserDefaults.standard.spotifyAccessToken = _accessToken.access_token 49    //ここで画面遷移を呼びたいが呼ばれない 50 self?.output.showList() 51 } 52 53 } 54 55} 56

LoginViewController.swift

1import UIKit 2 3final class LoginViewController: UIViewController { 4 5 @IBOutlet weak var loginButton: UIButton!{ 6 didSet { 7 loginButton.addTarget(self, action: #selector(tapAuthButton), for: .touchUpInside) 8 } 9 } 10 11 @objc private func tapAuthButton(){ 12 UIApplication.shared.open(API.shared.oAuthURL,options: [:]) 13 } 14 15 override func viewDidLoad() { 16 super.viewDidLoad() 17 } 18 19 private var presenter: MVPLoginPresenterInput! 20 func inject(presenter: MVPLoginPresenterInput) { 21 self.presenter = presenter 22 } 23} 24 25extension LoginViewController:MVPLoginPresenterOutput{ 26 func openURL(url: URL) { 27 presenter.open(url: url) 28 } 29 30 func showList() { 31  //ここが呼ばれない 32 Router.shared.showList(from: self) 33 } 34 35}

デバッグプリントで確認しても、アクセストークンキーはちゃんと受け取れてるので
遷移のメソッドだけ呼ばれていません。

承認が必要なAPIをMVPで作成するのが初なので、どこが間違っているのかわからない状況です…

お分かりになる方、ご教授いただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問