SlideShare a Scribd company logo
1 of 46
Download to read offline


📦










🤔
override func viewDidLoad() {
super.viewDidLoad()
// HUD
MBProgressHUD.showAdded(to: view, animated: true)
Alamofire.request("https://hogefuga.com/piyo").responseJSON {
[weak self] response in
guard response.error == nil else { return }
guard let data = response.data else { return }
guard let piyo = String(data: data, encoding: .utf8) else { return }
guard let weakSelf = self else { return }
// UI
weakSelf.piyoLabel.text = piyo
DispatchQueue.main.async { [weak self] in
guard let s = self else { return }
MBProgressHUD.hideAllHUDs(for: s.view, animated: true)
}
}
}
🤔
override func viewDidLoad() {
super.viewDidLoad()
metadataObjectTypesButton.isEnabled = false
sessionPresetsButton.isEnabled = false
cameraButton.isEnabled = false
zoomSlider.isEnabled = false
previewView.addGestureRecognizer(openBarcodeURLGestureRecognizer)
previewView.session = session
switch AVCaptureDevice.authorizationStatus(forMediaType: .video) {
case .authorized:
break
case .notDetermined:
sessionQueue.suspend()
AVCaptureDevice.requestAccess(forMediaType: .video, completionHandler: { granted in
if !granted {
self.setupResult = .notAuthorized
}
self.sessionQueue.resume()
})
default:
setupResult = .notAuthorized
}
sessionQueue.async {
self.configureSession()
}
}
























































🤔
override func viewDidLoad() {
super.viewDidLoad()
// HUD
MBProgressHUD.showAdded(to: view, animated: true)
Alamofire.request("https://hogefuga.com/piyo").responseJSON {
[weak self] response in
guard response.error == nil else { return }
guard let data = response.data else { return }
guard let piyo = String(data: data, encoding: .utf8) else { return }
guard let weakSelf = self else { return }
// UI
weakSelf.piyoLabel.text = piyo
DispatchQueue.main.async { [weak self] in
guard let s = self else { return }
MBProgressHUD.hideAllHUDs(for: s.view, animated: true)
}
}
}
🙆
class PiyoViewControllerImpl: UIViewController {

var piyoPresenter: PiyoPresenter!

@IBOutlet weak var piyoLabel: UILabel!

override func viewDidLoad() {
super.viewDidLoad()
piyoPresenter.readyForDisplay()
}
}



extension PiyoViewControllerImpl: PiyoViewController {
func showProgress() {
MBProgressHUD.showAdded(to: view, animated: true)
}
func hideProgress() {
DispatchQueue.main.async { [weak self] in
guard let weakSelf = self else { return }
MBProgressHUD.hideAllHUDs(for: weakSelf.view, animated: true)
}
}
func showPiyo(piyo: String) {
piyoLabel.text = piyo
}
}




















protocol StatsViewController: class {
func showProfile(_ profile: Profile)
func reloadTableView()
}
final class StatsViewControllerImpl: UIViewController {
var statsPresenter: StatsPresenter!
@IBOutlet weak var nicknameLabel: UILabel!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
statsPresenter.readyForDisplay(byMatch: .solo, region: .asia)
}
}
extension StatsViewControllerImpl: StatsViewController {
func showProfile(_ profile: Profile) {
DispatchQueue.main.async { [weak self] in
guard let weakSelf = self else { return }
weakSelf.nicknameLabel.text = profile.playerName
}
}
func reloadTableView() {
tableView.reloadData()
}
}
final class StatsViewControllerImpl: UIViewController {
var statsPresenter: StatsPresenter!
@IBOutlet weak var nicknameLabel: UILabel!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
statsPresenter.readyForDisplay(byMatch: .solo, region: .asia)
}
}
extension StatsViewControllerImpl: StatsViewController {
func showProfile(_ profile: Profile) {
DispatchQueue.main.async { [weak self] in
guard let weakSelf = self else { return }
weakSelf.nicknameLabel.text = profile.playerName
}
}
func reloadTableView() {
tableView.reloadData()
}
}


final class StatsViewControllerImpl: UIViewController {
var statsPresenter: StatsPresenter!
@IBOutlet weak var nicknameLabel: UILabel!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
statsPresenter.readyForDisplay(byMatch: .solo, region: .asia)
}
}
extension StatsViewControllerImpl: StatsViewController {
func showProfile(_ profile: Profile) {
DispatchQueue.main.async { [weak self] in
guard let weakSelf = self else { return }
weakSelf.nicknameLabel.text = profile.playerName
}
}
func reloadTableView() {
tableView.reloadData()
}
}


protocol StatsPresenter: class {
var stats: Stats! { get }
func readyForDisplay(byMatsh match: Match, region: Region)
}
final class StatsPresenterImpl: StatsPresenter {
private let pubgTrackerDataStore = PubgTrackerDataStore()
private weak var statsViewController: StatsViewController!
private var nickname: String!
var stats: Stats!
init(statsViewController: StatsViewController, nickname: String) {
self.statsViewController = statsViewController
self.nickname = nickname
}
func readyForDisplay(byMatsh match: Match, region: Region) {
pubgTrackerDataStore.fetchPubgTracker(byNickname: nickname) {
[weak self] stats in
guard let weakSelf = self else { return }
weakSelf.stats = stats
weakSelf.statsViewController.reloadTableView()
weakSelf.statsViewController.showProfile(profile)
}
}
}
final class StatsPresenterImpl: StatsPresenter {
private let pubgTrackerDataStore = PubgTrackerDataStore()
private weak var statsViewController: StatsViewController!
private var nickname: String!
var stats: Stats!
init(statsViewController: StatsViewController, nickname: String) {
self.statsViewController = statsViewController
self.nickname = nickname
}
func readyForDisplay(byMatsh match: Match, region: Region) {
pubgTrackerDataStore.fetchPubgTracker(byNickname: nickname) {
[weak self] stats in
guard let weakSelf = self else { return }
weakSelf.stats = stats
weakSelf.statsViewController.reloadTableView()
weakSelf.statsViewController.showProfile(profile)
}
}
}
final class StatsPresenterImpl: StatsPresenter {
private let pubgTrackerDataStore = PubgTrackerDataStore()
private weak var statsViewController: StatsViewController!
private var nickname: String!
var stats: Stats!
init(statsViewController: StatsViewController, nickname: String) {
self.statsViewController = statsViewController
self.nickname = nickname
}
func readyForDisplay(byMatsh match: Match, region: Region) {
pubgTrackerDataStore.fetchPubgTracker(byNickname: nickname) {
[weak self] stats in
guard let weakSelf = self else { return }
weakSelf.stats = stats
weakSelf.statsViewController.reloadTableView()
weakSelf.statsViewController.showProfile(profile)
}
}
}


final class StatsViewControllerImpl: UIViewController {
var statsPresenter: StatsPresenter!
@IBOutlet weak var nicknameLabel: UILabel!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
statsPresenter.readyForDisplay(byMatch: .solo, region: .asia)
}
}
extension StatsViewControllerImpl: StatsViewController {
func showProfile(_ profile: Profile) {
DispatchQueue.main.async { [weak self] in
guard let weakSelf = self else { return }
weakSelf.nicknameLabel.text = profile.playerName
}
}
func reloadTableView() {
tableView.reloadData()
}
}





































More Related Content

What's hot

こんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツールこんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツールdcubeio
 
GraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることGraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることShingo Fukui
 
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介 【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介 日本マイクロソフト株式会社
 
AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介
AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介
AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介KLab Inc. / Tech
 
FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術dena_study
 
リクルートにおけるデータのインフラ化への取組
リクルートにおけるデータのインフラ化への取組リクルートにおけるデータのインフラ化への取組
リクルートにおけるデータのインフラ化への取組Recruit Technologies
 
もしSIerのエンジニアがSRE本を読んだら
もしSIerのエンジニアがSRE本を読んだらもしSIerのエンジニアがSRE本を読んだら
もしSIerのエンジニアがSRE本を読んだらTomoki Ando
 
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)Ken Morishita
 
AI時代の要件定義
AI時代の要件定義AI時代の要件定義
AI時代の要件定義Zenji Kanzaki
 
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)Kazuya Sugimoto
 
MMOGで考えるゲームデザイン
MMOGで考えるゲームデザインMMOGで考えるゲームデザイン
MMOGで考えるゲームデザインKatsumi Mizushima
 
プログラマが欲しい仕様書とは
プログラマが欲しい仕様書とはプログラマが欲しい仕様書とは
プログラマが欲しい仕様書とはKatsutoshi Makino
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門torisoup
 
[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送
[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送
[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送Google Cloud Platform - Japan
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞いiOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞いKen Morishita
 
スマホ(Android・iPhone)でWebRTC
スマホ(Android・iPhone)でWebRTCスマホ(Android・iPhone)でWebRTC
スマホ(Android・iPhone)でWebRTCNatsuki Yamanaka
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと増田 亨
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 

What's hot (20)

こんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツールこんなに使える!今どきのAPIドキュメンテーションツール
こんなに使える!今どきのAPIドキュメンテーションツール
 
GraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることGraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ること
 
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介 【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
 
AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介
AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介
AirLab導入でテストコストの大幅削減と品質向上! 数十台の端末を一斉に全自動テストできる社内DeviceFarmについてご紹介
 
FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術FINAL FANTASY Record Keeperのマスターデータを支える技術
FINAL FANTASY Record Keeperのマスターデータを支える技術
 
リクルートにおけるデータのインフラ化への取組
リクルートにおけるデータのインフラ化への取組リクルートにおけるデータのインフラ化への取組
リクルートにおけるデータのインフラ化への取組
 
もしSIerのエンジニアがSRE本を読んだら
もしSIerのエンジニアがSRE本を読んだらもしSIerのエンジニアがSRE本を読んだら
もしSIerのエンジニアがSRE本を読んだら
 
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)知らないと損するアプリ開発におけるStateMachineの活用法(full版)
知らないと損するアプリ開発におけるStateMachineの活用法(full版)
 
AI時代の要件定義
AI時代の要件定義AI時代の要件定義
AI時代の要件定義
 
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
 
MMOGで考えるゲームデザイン
MMOGで考えるゲームデザインMMOGで考えるゲームデザイン
MMOGで考えるゲームデザイン
 
プログラマが欲しい仕様書とは
プログラマが欲しい仕様書とはプログラマが欲しい仕様書とは
プログラマが欲しい仕様書とは
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門
 
[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送
[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送
[Cloud OnAir] BigQuery の仕組みからベストプラクティスまでのご紹介 2018年9月6日 放送
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞いiOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い
 
スマホ(Android・iPhone)でWebRTC
スマホ(Android・iPhone)でWebRTCスマホ(Android・iPhone)でWebRTC
スマホ(Android・iPhone)でWebRTC
 
世界最強のソフトウェアアーキテクト
世界最強のソフトウェアアーキテクト世界最強のソフトウェアアーキテクト
世界最強のソフトウェアアーキテクト
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 

Similar to 節子、それViewControllerやない...、FatViewControllerや...。

[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM patternNAVER Engineering
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcionalNSCoder Mexico
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesRiad Benguella
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Tsuyoshi Yamamoto
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Swift Delhi: Practical POP
Swift Delhi: Practical POPSwift Delhi: Practical POP
Swift Delhi: Practical POPNatasha Murashev
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developersPavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon Berlin
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingNatasha Murashev
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818Shahzain Saeed
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftPROIDEA
 
Prescribing RX Responsibly
Prescribing RX ResponsiblyPrescribing RX Responsibly
Prescribing RX ResponsiblyNareg Khoshafian
 
Smooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionViewSmooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionViewAndrea Prearo
 

Similar to 節子、それViewControllerやない...、FatViewControllerや...。 (20)

[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Intro programacion funcional
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisables
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Swift Delhi: Practical POP
Swift Delhi: Practical POPSwift Delhi: Practical POP
Swift Delhi: Practical POP
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Deep dive into Oracle ADF
Deep dive into Oracle ADFDeep dive into Oracle ADF
Deep dive into Oracle ADF
 
Practical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
 
Practialpop 160510130818
Practialpop 160510130818Practialpop 160510130818
Practialpop 160510130818
 
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in SwiftMCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
MCE^3 - Natasha Murashev - Practical Protocol-Oriented Programming in Swift
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Prescribing RX Responsibly
Prescribing RX ResponsiblyPrescribing RX Responsibly
Prescribing RX Responsibly
 
Smooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionViewSmooth scrolling in UITableView and UICollectionView
Smooth scrolling in UITableView and UICollectionView
 

More from Kenji Tanaka

FatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdc
FatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdcFatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdc
FatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdcKenji Tanaka
 
リリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_night
リリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_nightリリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_night
リリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_nightKenji Tanaka
 
ポストモーテムやってみた #yjbonfire
ポストモーテムやってみた #yjbonfireポストモーテムやってみた #yjbonfire
ポストモーテムやってみた #yjbonfireKenji Tanaka
 
2つの同期 4つの状態 #pixiv_ios_arch
2つの同期 4つの状態 #pixiv_ios_arch2つの同期 4つの状態 #pixiv_ios_arch
2つの同期 4つの状態 #pixiv_ios_archKenji Tanaka
 
2つの同期 4つの状態 #app_mp
2つの同期 4つの状態 #app_mp2つの同期 4つの状態 #app_mp
2つの同期 4つの状態 #app_mpKenji Tanaka
 
2つの同期 4つの状態 #roppongiswift
2つの同期 4つの状態 #roppongiswift2つの同期 4つの状態 #roppongiswift
2つの同期 4つの状態 #roppongiswiftKenji Tanaka
 
トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_night
トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_nightトークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_night
トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_nightKenji Tanaka
 
よく使うテストヘルパーの紹介 #ios_test_night
よく使うテストヘルパーの紹介 #ios_test_nightよく使うテストヘルパーの紹介 #ios_test_night
よく使うテストヘルパーの紹介 #ios_test_nightKenji Tanaka
 
Swiftで聞いておぼえるテスト書き
Swiftで聞いておぼえるテスト書きSwiftで聞いておぼえるテスト書き
Swiftで聞いておぼえるテスト書きKenji Tanaka
 
設計時空のリファクタリング
設計時空のリファクタリング設計時空のリファクタリング
設計時空のリファクタリングKenji Tanaka
 
WACATE 2018 Summer
WACATE 2018 SummerWACATE 2018 Summer
WACATE 2018 SummerKenji Tanaka
 
テスト駆動開発入門 by Swift
テスト駆動開発入門 by Swiftテスト駆動開発入門 by Swift
テスト駆動開発入門 by SwiftKenji Tanaka
 
An iOS Engineer challenges Web.
An iOS Engineer challenges Web.An iOS Engineer challenges Web.
An iOS Engineer challenges Web.Kenji Tanaka
 
エンジニアのためのブログ講座Ver4
エンジニアのためのブログ講座Ver4エンジニアのためのブログ講座Ver4
エンジニアのためのブログ講座Ver4Kenji Tanaka
 
TDDやってみよ
TDDやってみよTDDやってみよ
TDDやってみよKenji Tanaka
 
ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品
ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品
ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品Kenji Tanaka
 
iOS 11からのDeviceCheck #とは
iOS 11からのDeviceCheck #とはiOS 11からのDeviceCheck #とは
iOS 11からのDeviceCheck #とはKenji Tanaka
 
設計に答えはないから探してみよう
設計に答えはないから探してみよう設計に答えはないから探してみよう
設計に答えはないから探してみようKenji Tanaka
 
iOS 11からのアプリ間ファイル共有
iOS 11からのアプリ間ファイル共有iOS 11からのアプリ間ファイル共有
iOS 11からのアプリ間ファイル共有Kenji Tanaka
 
iOS 11からのアプリ間ファイル共有_公開用
iOS 11からのアプリ間ファイル共有_公開用iOS 11からのアプリ間ファイル共有_公開用
iOS 11からのアプリ間ファイル共有_公開用Kenji Tanaka
 

More from Kenji Tanaka (20)

FatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdc
FatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdcFatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdc
FatViewControllerを安全に書き換える方法が見つからなかったので、どういう痛みを許容するか考えた #iosdc
 
リリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_night
リリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_nightリリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_night
リリース前のリグレッションテストがめんどい!のでMagic PodでUIテストを試してみる #pixiv_app_night
 
ポストモーテムやってみた #yjbonfire
ポストモーテムやってみた #yjbonfireポストモーテムやってみた #yjbonfire
ポストモーテムやってみた #yjbonfire
 
2つの同期 4つの状態 #pixiv_ios_arch
2つの同期 4つの状態 #pixiv_ios_arch2つの同期 4つの状態 #pixiv_ios_arch
2つの同期 4つの状態 #pixiv_ios_arch
 
2つの同期 4つの状態 #app_mp
2つの同期 4つの状態 #app_mp2つの同期 4つの状態 #app_mp
2つの同期 4つの状態 #app_mp
 
2つの同期 4つの状態 #roppongiswift
2つの同期 4つの状態 #roppongiswift2つの同期 4つの状態 #roppongiswift
2つの同期 4つの状態 #roppongiswift
 
トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_night
トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_nightトークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_night
トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_night
 
よく使うテストヘルパーの紹介 #ios_test_night
よく使うテストヘルパーの紹介 #ios_test_nightよく使うテストヘルパーの紹介 #ios_test_night
よく使うテストヘルパーの紹介 #ios_test_night
 
Swiftで聞いておぼえるテスト書き
Swiftで聞いておぼえるテスト書きSwiftで聞いておぼえるテスト書き
Swiftで聞いておぼえるテスト書き
 
設計時空のリファクタリング
設計時空のリファクタリング設計時空のリファクタリング
設計時空のリファクタリング
 
WACATE 2018 Summer
WACATE 2018 SummerWACATE 2018 Summer
WACATE 2018 Summer
 
テスト駆動開発入門 by Swift
テスト駆動開発入門 by Swiftテスト駆動開発入門 by Swift
テスト駆動開発入門 by Swift
 
An iOS Engineer challenges Web.
An iOS Engineer challenges Web.An iOS Engineer challenges Web.
An iOS Engineer challenges Web.
 
エンジニアのためのブログ講座Ver4
エンジニアのためのブログ講座Ver4エンジニアのためのブログ講座Ver4
エンジニアのためのブログ講座Ver4
 
TDDやってみよ
TDDやってみよTDDやってみよ
TDDやってみよ
 
ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品
ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品
ストレス社会に生きる、iOSエンジニアにオススメする百合の世界と作品
 
iOS 11からのDeviceCheck #とは
iOS 11からのDeviceCheck #とはiOS 11からのDeviceCheck #とは
iOS 11からのDeviceCheck #とは
 
設計に答えはないから探してみよう
設計に答えはないから探してみよう設計に答えはないから探してみよう
設計に答えはないから探してみよう
 
iOS 11からのアプリ間ファイル共有
iOS 11からのアプリ間ファイル共有iOS 11からのアプリ間ファイル共有
iOS 11からのアプリ間ファイル共有
 
iOS 11からのアプリ間ファイル共有_公開用
iOS 11からのアプリ間ファイル共有_公開用iOS 11からのアプリ間ファイル共有_公開用
iOS 11からのアプリ間ファイル共有_公開用
 

Recently uploaded

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 

Recently uploaded (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 

節子、それViewControllerやない...、FatViewControllerや...。

  • 1.
  • 3.
  • 4.
  • 6.
  • 7.
  • 8. 🤔 override func viewDidLoad() { super.viewDidLoad() // HUD MBProgressHUD.showAdded(to: view, animated: true) Alamofire.request("https://hogefuga.com/piyo").responseJSON { [weak self] response in guard response.error == nil else { return } guard let data = response.data else { return } guard let piyo = String(data: data, encoding: .utf8) else { return } guard let weakSelf = self else { return } // UI weakSelf.piyoLabel.text = piyo DispatchQueue.main.async { [weak self] in guard let s = self else { return } MBProgressHUD.hideAllHUDs(for: s.view, animated: true) } } }
  • 9. 🤔 override func viewDidLoad() { super.viewDidLoad() metadataObjectTypesButton.isEnabled = false sessionPresetsButton.isEnabled = false cameraButton.isEnabled = false zoomSlider.isEnabled = false previewView.addGestureRecognizer(openBarcodeURLGestureRecognizer) previewView.session = session switch AVCaptureDevice.authorizationStatus(forMediaType: .video) { case .authorized: break case .notDetermined: sessionQueue.suspend() AVCaptureDevice.requestAccess(forMediaType: .video, completionHandler: { granted in if !granted { self.setupResult = .notAuthorized } self.sessionQueue.resume() }) default: setupResult = .notAuthorized } sessionQueue.async { self.configureSession() } }
  • 11.
  • 12.
  • 15.
  • 16.
  • 17.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26. 🤔 override func viewDidLoad() { super.viewDidLoad() // HUD MBProgressHUD.showAdded(to: view, animated: true) Alamofire.request("https://hogefuga.com/piyo").responseJSON { [weak self] response in guard response.error == nil else { return } guard let data = response.data else { return } guard let piyo = String(data: data, encoding: .utf8) else { return } guard let weakSelf = self else { return } // UI weakSelf.piyoLabel.text = piyo DispatchQueue.main.async { [weak self] in guard let s = self else { return } MBProgressHUD.hideAllHUDs(for: s.view, animated: true) } } }
  • 27. 🙆 class PiyoViewControllerImpl: UIViewController {
 var piyoPresenter: PiyoPresenter!
 @IBOutlet weak var piyoLabel: UILabel!
 override func viewDidLoad() { super.viewDidLoad() piyoPresenter.readyForDisplay() } }
 
 extension PiyoViewControllerImpl: PiyoViewController { func showProgress() { MBProgressHUD.showAdded(to: view, animated: true) } func hideProgress() { DispatchQueue.main.async { [weak self] in guard let weakSelf = self else { return } MBProgressHUD.hideAllHUDs(for: weakSelf.view, animated: true) } } func showPiyo(piyo: String) { piyoLabel.text = piyo } }
  • 28.
  • 29. 
 
 
 
 
 
 
 
 
 protocol StatsViewController: class { func showProfile(_ profile: Profile) func reloadTableView() }
  • 30. final class StatsViewControllerImpl: UIViewController { var statsPresenter: StatsPresenter! @IBOutlet weak var nicknameLabel: UILabel! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() statsPresenter.readyForDisplay(byMatch: .solo, region: .asia) } } extension StatsViewControllerImpl: StatsViewController { func showProfile(_ profile: Profile) { DispatchQueue.main.async { [weak self] in guard let weakSelf = self else { return } weakSelf.nicknameLabel.text = profile.playerName } } func reloadTableView() { tableView.reloadData() } }
  • 31. final class StatsViewControllerImpl: UIViewController { var statsPresenter: StatsPresenter! @IBOutlet weak var nicknameLabel: UILabel! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() statsPresenter.readyForDisplay(byMatch: .solo, region: .asia) } } extension StatsViewControllerImpl: StatsViewController { func showProfile(_ profile: Profile) { DispatchQueue.main.async { [weak self] in guard let weakSelf = self else { return } weakSelf.nicknameLabel.text = profile.playerName } } func reloadTableView() { tableView.reloadData() } }
  • 32. 
 final class StatsViewControllerImpl: UIViewController { var statsPresenter: StatsPresenter! @IBOutlet weak var nicknameLabel: UILabel! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() statsPresenter.readyForDisplay(byMatch: .solo, region: .asia) } } extension StatsViewControllerImpl: StatsViewController { func showProfile(_ profile: Profile) { DispatchQueue.main.async { [weak self] in guard let weakSelf = self else { return } weakSelf.nicknameLabel.text = profile.playerName } } func reloadTableView() { tableView.reloadData() } }
  • 33. 
 protocol StatsPresenter: class { var stats: Stats! { get } func readyForDisplay(byMatsh match: Match, region: Region) }
  • 34. final class StatsPresenterImpl: StatsPresenter { private let pubgTrackerDataStore = PubgTrackerDataStore() private weak var statsViewController: StatsViewController! private var nickname: String! var stats: Stats! init(statsViewController: StatsViewController, nickname: String) { self.statsViewController = statsViewController self.nickname = nickname } func readyForDisplay(byMatsh match: Match, region: Region) { pubgTrackerDataStore.fetchPubgTracker(byNickname: nickname) { [weak self] stats in guard let weakSelf = self else { return } weakSelf.stats = stats weakSelf.statsViewController.reloadTableView() weakSelf.statsViewController.showProfile(profile) } } }
  • 35. final class StatsPresenterImpl: StatsPresenter { private let pubgTrackerDataStore = PubgTrackerDataStore() private weak var statsViewController: StatsViewController! private var nickname: String! var stats: Stats! init(statsViewController: StatsViewController, nickname: String) { self.statsViewController = statsViewController self.nickname = nickname } func readyForDisplay(byMatsh match: Match, region: Region) { pubgTrackerDataStore.fetchPubgTracker(byNickname: nickname) { [weak self] stats in guard let weakSelf = self else { return } weakSelf.stats = stats weakSelf.statsViewController.reloadTableView() weakSelf.statsViewController.showProfile(profile) } } }
  • 36. final class StatsPresenterImpl: StatsPresenter { private let pubgTrackerDataStore = PubgTrackerDataStore() private weak var statsViewController: StatsViewController! private var nickname: String! var stats: Stats! init(statsViewController: StatsViewController, nickname: String) { self.statsViewController = statsViewController self.nickname = nickname } func readyForDisplay(byMatsh match: Match, region: Region) { pubgTrackerDataStore.fetchPubgTracker(byNickname: nickname) { [weak self] stats in guard let weakSelf = self else { return } weakSelf.stats = stats weakSelf.statsViewController.reloadTableView() weakSelf.statsViewController.showProfile(profile) } } }
  • 37. 
 final class StatsViewControllerImpl: UIViewController { var statsPresenter: StatsPresenter! @IBOutlet weak var nicknameLabel: UILabel! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() statsPresenter.readyForDisplay(byMatch: .solo, region: .asia) } } extension StatsViewControllerImpl: StatsViewController { func showProfile(_ profile: Profile) { DispatchQueue.main.async { [weak self] in guard let weakSelf = self else { return } weakSelf.nicknameLabel.text = profile.playerName } } func reloadTableView() { tableView.reloadData() } } 

  • 39.
  • 40.
  • 42.
  • 44.
  • 45.