HomeiOS Developmentios - Passing context with information MVVM

ios – Passing context with information MVVM


I’ve a MainViewController,MainViewCoordinator,MainViewModel, MainView+Delegates and GameOverController,GameOverCoordinator.
I wish to go the correctAnswer, correctAnswerImage and the sport.rating from my Predominant to the GameOver and present the info, I take advantage of this code to open GameOver however I do not know the best way to ship information to the GameOver.

context?.initialize(coordinator: GameOverCoordinator(context: context!))

MainViewController



import UIKit

class MainViewController: UIViewController {
    non-public var stackView: UIStackView!
    var pokemonImage: UIImageView!
    non-public var titleLabel: UILabel!
    non-public var scoreLabel: UILabel!
    non-public var messageLabel: UILabel!

    var randomPokemons: [PokemonModel] = [] {
        didSet {
            setButtonTitles()
        }
    }

    // Array to retailer references to OptionButtons
    non-public var optionButtons: [UIButton] = []
    var correctAnswer: String = ""
    var correctAnswerImage: String = ""

    lazy var recreation = GameModel()

    // MARK: - Properties

    weak var coordinator: Coordinator?
    weak var context: Context?
    var viewModel: MainViewModel!

    override func viewDidLoad() {
        tremendous.viewDidLoad()
        view.backgroundColor = .systemGray6
        viewModel.apiCaller.delegate = self

        setUpView()
        setUpLayout()
        viewModel.fetchPokemon()
        messageLabel.textual content = " "
    }

    non-public func setUpView() {
        titleLabel = UILabel()
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        titleLabel.textual content = "Pokémon?"
        titleLabel.font = UIFont(identify: "Arial Rounded MT Daring", measurement: 24)
        titleLabel.numberOfLines = 0
        titleLabel.textAlignment = .middle

        scoreLabel = UILabel()
        scoreLabel.translatesAutoresizingMaskIntoConstraints = false
        scoreLabel.textual content = "Rating: 0"
        scoreLabel.numberOfLines = 0
        scoreLabel.textAlignment = .middle

        pokemonImage = UIImageView(picture: viewModel.getPokemonImage())
        pokemonImage.translatesAutoresizingMaskIntoConstraints = false
        pokemonImage.heightAnchor.constraint(equalToConstant: 200).isActive = true
        pokemonImage.contentMode = .scaleAspectFit

        messageLabel = UILabel()
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.textual content = "Sure, is a Pikachu"
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .middle

        // stackView = UIStackView(arrangedSubviews: [nameOption1Button, nameOption2Button, nameOption3Button, nameOption4Button])
        stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        stackView.distribution = .equalSpacing
        stackView.spacing = 24

        // UIButtons
        ["Pokemon 1", "Pokemon 2", "Pokemon 3", "Pokemon 4"].forEach { pokemonName in
            let button = UIButton(sort: .system)
            button.translatesAutoresizingMaskIntoConstraints = false
            button.setTitle(pokemonName, for: .regular)
            button.setTitleColor(.black, for: .regular)
            button.backgroundColor = .white
            button.heightAnchor.constraint(equalToConstant: 50).isActive = true
            button.layer.shadowOffset = CGSize(width: 0.0, top: 2.0)
            button.layer.shadowOpacity = 1.0
            button.layer.shadowRadius = 0
            button.layer.masksToBounds = false
            button.layer.cornerRadius = 10.0
            button.tag = 10
            button.addTarget(self, motion: #selector(optionPressed), for: .touchUpInside)

            stackView.addArrangedSubview(button)

            // Add the button to the array
            optionButtons.append(button)
        }
    }

    non-public func setUpLayout() {
        view.addSubview(titleLabel)
        view.addSubview(scoreLabel)
        view.addSubview(pokemonImage)
        view.addSubview(messageLabel)
        view.addSubview(stackView)

        /*
         [nameOption1Button, nameOption2Button, nameOption3Button, nameOption4Button].forEach {
             $0?.heightAnchor.constraint(equalToConstant: 50).isActive = true
         }
          */

        NSLayoutConstraint.activate([
            titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            scoreLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 2),
            scoreLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            pokemonImage.topAnchor.constraint(equalTo: scoreLabel.bottomAnchor, constant: 50),
            pokemonImage.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            messageLabel.topAnchor.constraint(equalTo: pokemonImage.bottomAnchor, constant: 2),
            messageLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),

            stackView.topAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 40),
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            // Width anchor 20 left x 20 right
            stackView.widthAnchor.constraint(equalToConstant: view.bounds.width - 40),
        ])
    }

    @objc func optionPressed(sender: UIButton!) {
        if let userAnswer = sender.title(for: .regular) {
            if recreation.checkAnswer(userAnswer, correctAnswer) {
                messageLabel.textual content = "Si, es un (userAnswer.capitalized)"
                scoreLabel.textual content = "Puntaje: (recreation.rating)"

                sender.layer.borderColor = UIColor.systemGreen.cgColor
                sender.layer.borderWidth = 2

                let url = URL(string: correctAnswerImage)
                pokemonImage.kf.setImage(with: url)

                Timer.scheduledTimer(withTimeInterval: 0.8, repeats: false) { [self] _ in
                    viewModel.fetchPokemon()
                    messageLabel.textual content = " "
                    sender.layer.borderWidth = 0
                }
            } else {
                /* sender.layer.borderColor = UIColor.systemRed.cgColor
                 sender.layer.borderWidth = 2

                 messageLabel.textual content = "Noo, es un (correctAnswer.capitalized)"
                 // Convertir Url en imagen
                 let url = URL(string: correctAnswerImage)
                 pokemonImage.kf.setImage(with: url)

                 Timer.scheduledTimer(withTimeInterval: 0.8, repeats: false) { [self] _ in
                     resetGame()
                     sender.layer.borderWidth = 0
                 } */
                context?.initialize(coordinator: GameOverCoordinator(context: context!))
                //self.performSegue(withIdentifier: "GameOverController", sender: self)
                resetGame()
            }
        }
    }

    func setButtonTitles() {
        // Iterate by the buttons and replace their titles
        for (index, button) in optionButtons.enumerated() {
            if index < randomPokemons.rely {
                DispatchQueue.major.sync { [self] in
                    button.setTitle(randomPokemons[safe: index]?.identify.capitalized, for: .regular)
                }
            } /* else {
                 // Deal with the case the place there are fewer Pokemon names than buttons
                 button.setTitle("", for: .regular)
             }*/
        }
    }

    func resetGame() {
        viewModel.fetchPokemon()
        recreation.setScore(rating: 0)
        scoreLabel.textual content = "Puntaje: (recreation.rating)"
        messageLabel.textual content = " "
    }
}

MainViewCoordinator


class MainViewCoordinator: Coordinator {
    var context: Context?
    let apiCaller = ApiCaller()

    init(context: Context) {
        self.context = context
    }

    func begin() {
        let viewController = MainViewController()
        viewController.viewModel = MainViewModel(apiCaller: apiCaller)
        viewController.coordinator = self
        viewController.context = context
        context?.push(viewController: viewController)
    }
}

MainViewModel

class MainViewModel {
    let apiCaller: ApiCaller
    
    init(apiCaller: ApiCaller){
        self.apiCaller = apiCaller
    }

    func getPokemonImage() -> UIImage {
        return UIImage(named: "pikachu")!
    }

    func getTitleButton() -> String {
        return "Pokemon"
    }

    func fetchPokemon() {
        apiCaller.performRequest(with: NetworkConstant.shared.pokemonUrl)
    }
    
    func fetchImage(url: String){
        apiCaller.performRequestImage(with: url)
    }
    
}

GameOverController


import UIKit
import Kingfisher

class GameOverController: UIViewController {
    
    non-public var pokemonImage: UIImageView!
    non-public var titleLabel: UILabel!
    non-public var scoreLabel: UILabel!
    non-public var messageLabel: UILabel!
    non-public var playAgainButton: UIButton!

    var pokemonName: String = ""
    var pokemonImageUrl: String = ""
    var finalScore = 0

    // MARK: - Properties

    weak var coordinator: Coordinator?
    weak var context: Context?
    var viewModel: GameOverModel!

    override func viewDidLoad() {
        tremendous.viewDidLoad()
        view.backgroundColor = .systemGray6

        setUpView()
        setUpLayout()
    }

    non-public func setUpView() {
        titleLabel = UILabel()
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        titleLabel.textual content = "¡OOOPS!"
        titleLabel.font = UIFont(identify: "Arial Rounded MT Daring", measurement: 24)
        titleLabel.numberOfLines = 0
        titleLabel.textAlignment = .middle

        pokemonImage = UIImageView()
        pokemonImage.kf.setImage(with: URL(string: pokemonImageUrl))
        pokemonImage.translatesAutoresizingMaskIntoConstraints = false
        pokemonImage.heightAnchor.constraint(equalToConstant: 200).isActive = true
        pokemonImage.contentMode = .scaleAspectFit

        messageLabel = UILabel()
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.textual content = "No, is (pokemonName)"
        messageLabel.numberOfLines = 0
        messageLabel.textAlignment = .middle

        scoreLabel = UILabel()
        scoreLabel.translatesAutoresizingMaskIntoConstraints = false
        scoreLabel.textual content = "Your Rating (finalScore)"
        scoreLabel.numberOfLines = 0
        scoreLabel.textAlignment = .middle

        playAgainButton = UIButton()
        playAgainButton.translatesAutoresizingMaskIntoConstraints = false
        playAgainButton.setTitle("Play once more", for: .regular)
        playAgainButton.setTitleColor(.white, for: .regular)
        playAgainButton.backgroundColor = .systemBlue
        playAgainButton.addTarget(self, motion: #selector(playAgain), for: .touchUpInside)
    }

    non-public func setUpLayout() {
        view.addSubview(titleLabel)
        view.addSubview(pokemonImage)
        view.addSubview(messageLabel)
        view.addSubview(scoreLabel)
        view.addSubview(playAgainButton)

        NSLayoutConstraint.activate([
            titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24),
            titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24),

            pokemonImage.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 120),
            pokemonImage.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24),
            pokemonImage.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24),

            messageLabel.topAnchor.constraint(equalTo: pokemonImage.bottomAnchor, constant: 15),
            messageLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24),
            messageLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24),

            scoreLabel.topAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 120),
            scoreLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24),
            scoreLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24),

            playAgainButton.topAnchor.constraint(equalTo: scoreLabel.bottomAnchor, constant: 80),
            playAgainButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24),
            playAgainButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24),
        ])
    }

    @objc func playAgain() {
        context?.initialize(coordinator: MainViewCoordinator(context: context!))
        //dismiss(animated: true)
    }
}

GameOverCoordinator


import Basis

class GameOverCoordinator: Coordinator {
    var context: Context?

    init(context: Context) {
        self.context = context
    }

    func begin() {
        let viewController = GameOverController()
        viewController.viewModel = GameOverModel()
        viewController.coordinator = self
        viewController.context = context
        context?.push(viewController: viewController)
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments