Xcode: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
Line 100: Line 100:
import Foundation
import Foundation


protocol AnyInteractor2 {
protocol AnyInteractor2 {
     var presenter: AnyPresenter? { get set }
     var presenter: AnyPresenter? { get set }
     func getUsers()
     func getUsers()
Line 131: Line 131:
}
}
</syntaxhighlight>
</syntaxhighlight>
==Presenter==
==Presenter==
<syntaxhighlight lang="swift">
<syntaxhighlight lang="swift">

Revision as of 04:48, 9 July 2022

Introduction

This page is for Xcode. We started on Xcode 13

Layouts

This is a bit like Android Studio and very much like Java where you build views in views and constraint where it makes sense. In this example we build three views, place them in a vertical stack view and constraint that. For Dice we put them in a horizontal stack view. For the button text we add a constraint to the width. Not sure where margin comes in currently.



When happy select the view layouts with the command key ⌘ and select default background



Adding the constraint for the number was hard. Put it in a view and add a constraint to indent on the right.


VIPER

VIPER is a design pattern which seems to be associated with Apple

Really enjoyed the demonstration from Youtube. [[1]]

VIPER Source Example

View

import Foundation
import UIKit

protocol AnyView {
    var presenter: AnyPresenter? {get set}
    
    func update(with users: [User])
    func update(with error: String)
}

class UserViewController: UIViewController, AnyView, UITableViewDelegate, UITableViewDataSource   {
    var presenter: AnyPresenter?
    
    var users: [User] = []
    
    private let tableview: UITableView = {
        let table = UITableView()
        table.register(UITableViewCell.self,
                       forCellReuseIdentifier: "cell")
        table.isHidden = true
        return table
    }()
    
    private let label: UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.isHidden = true
        return label
    }()
    
    override func viewDidLoad() {
    
        super.viewDidLoad()
        view.addSubview(label)
        label.center = view.center
        view.backgroundColor = .systemBlue
        
        view.addSubview(tableview)
        tableview.delegate = self
        tableview.dataSource = self
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        tableview.frame = view.bounds
        label.frame = CGRect(x: 0, y: 0, width: 200, height: 50)
        label.center = view.center
        
    }
    
    func update(with users: [User]) {
        DispatchQueue.main.async {
            self.users = users
            self.tableview.reloadData()
            self.tableview.isHidden = false
        }
    }
    
    func update(with error: String) {
        print("Iain was ere", error)
        DispatchQueue.main.async {
            self.users = []
            self.label.text = error
            self.tableview.isHidden = true
            self.label.isHidden = false
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return users.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = users[indexPath.row].namess
        return cell
    }

}

Interactor

import Foundation

protocol AnyInteractor2 {
    var presenter: AnyPresenter? { get set }
    func getUsers()
}

class UserInteractor: AnyInteractor2 {
    
    var presenter: AnyPresenter?
    
    func getUsers() {
        guard let url  = URL(string: "https://jsonplaceholder.typicode.com/users") else  { return }
        let task = URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
            guard let data  = data, error == nil else {
                self?.presenter?.interactorDidFetchUsers(with: .failure(FetchError.failed))
                return
            }
            
            do {
                let entities = try JSONDecoder().decode([User].self, from: data)
                
                self?.presenter?.interactorDidFetchUsers(with: .success(entities))
            }
            catch {
                self?.presenter?.interactorDidFetchUsers(with: .failure(error))
            }
        }
                
        task.resume()
    }
}

Presenter

Entity

Router