/workshop

Primary LanguageSwift

Readme

Telechargement de project depuis github

git clone https://github.com/tommypeps/workshop.git

Explication cocoapods, usage et configuration

touch Podfile
nano Podfile

Fichier Podfile:

platform :ios, '8.0'

use_frameworks!

target 'Workshop' do
pod 'AFNetworking'
pod 'ObjectMapper', '~> 3.4'
pod 'AlamofireObjectMapper', '~> 5.2'
pod 'Kingfisher', '4.10.1'

end

Installation de dépendance:

pod install

Démarer le project:

open 'Workshop'.xcworkspace 

Definir l'importance du service et commencer la application depuis :

  • implémenter LaunchDTO
  • implémenter Launch
  • implémenter DTOConversor
  • implémenter LaunchService
  • implémenter LaunchDTO:
import ObjectMapper

class LaunchDTO: Mappable {

    var flightNumber = 0
    var launchSuccess = false
    var details = ""
    var missionName = ""
    var missionPathUrl = ""

    required init?(map: Map) {}

    func mapping(map: Map) {
        flightNumber <- map["flight_number"]
        launchSuccess <- map["launch_success"]
        details <- map["details"]
        missionName <- map["mission_name"]
        missionPathUrl <- map["links.mission_patch"]
    }
}
  • implémenter LaunchModel:
struct LaunchModel {
    var flightNumber = 0
    var launchSuccess = false
    var details = ""
    var missionName = ""
    var missionPathUrl = ""
}
  • implémener DTOConversor:
class LaunchDTOConversor {
    static func from(launchDTO: LaunchDTO) -> LaunchModel {
        var model = LaunchModel()
        model.flightNumber = launchDTO.flightNumber
        model.launchSuccess = launchDTO.launchSuccess
        model.details = launchDTO.details
        model.missionName = launchDTO.missionName
        model.missionPathUrl = launchDTO.missionPathUrl
        return model
    }
}
  • implémentater LaunchService:
import Alamofire
import AlamofireObjectMapper


class LaunchService {
    static func getLaunchs(success: (([LaunchModel]) -> Void)?, failure: ((Error) -> Void)? ) {
        let url = "https://api.spacexdata.com/v3/launches"
        Alamofire.request(url, method: .get).responseArray { (response: DataResponse<[LaunchDTO]>) in
            switch response.result {
                case .success(let lauchModelResponses):
                let models = lauchModelResponses.map({ LaunchDTOConversor.from(launchDTO: $0) })
                success?(models)
            case .failure(let error):
                failure?(error)
            }
        }
    }
} 
  • Tester que le service marche:
LaunchService.getLaunchs(success: { models in
    print(models)
}) { error in
    print(error)
}
  • Integration vue:
import Kingfisher

class LaunchCell: UITableViewCell {

    @IBOutlet var pathImage: UIImageView!
    @IBOutlet var missionLabel: UILabel!
    @IBOutlet var detailLabel: UILabel!

    func configureCell(model: LaunchModel) {
        if !model.missionPathUrl.isEmpty {
        pathImage.kf.setImage(with: model.missionPathUrl.url)
        }
        missionLabel.text = model.missionName
        detailLabel.text = model.details
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        pathImage.kf.cancelDownloadTask()
    }
}
  • Definition vue du cell:

  • Definition struct Module:

struct Launch {
    static let storyBoardName = "LaunchStorybord"

    struct Constant {
        static let alertTitle = "**alertTitle**"
        static let alertBody = "**alertBody**"
        static let confirmationButton = "**confirmationButton**"
    }

    enum LaunchCell: String, CaseIterable {
        case launchCell = "LaunchCell"
    }
}
  • Charge storyboard dans l'app:
let launchStorybord = UIStoryboard(name: Launch.storyBoardName, bundle: nil)
if let letLaunchViewController =  launchStorybord.instantiateInitialViewController() {
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = letLaunchViewController
    self.window?.makeKeyAndVisible()
}
  • Definition storybard cell:

  • Definiction ViewController: UIViewController

    • Configuration Cell
    • Configuration TableView
    • Registration cell
    • assignation delegate
    • Configuration Datasource
    • Configuration alert
    • Call service
    • Show alert/ reload info
import UIKit

class LaunchViewController: UIViewController {

    @IBOutlet var tableView: UITableView!

    var model = [LaunchModel]()
    var alertController: UIAlertController?

    override func viewDidLoad() {
        super.viewDidLoad()
        loadInformation()
        configureTableView()
    }   
}

extension LaunchViewController {

    private func configureTableView() {
        // Register cell
        let nib = UINib(nibName: Launch.LaunchCell.launchCell.rawValue, bundle: Bundle.main)
        tableView.register(nib, forCellReuseIdentifier: Launch.LaunchCell.launchCell.rawValue)
        // Configue datasource
        tableView.dataSource = self
        tableView.delegate = self
        tableView.estimatedRowHeight = 44.0
        tableView.rowHeight = UITableView.automaticDimension
    }

    private func loadInformation() {
        LaunchService.getLaunchs(success: { [weak self] launchModels in
            self?.model = launchModels
            self?.tableView.reloadData()
        }) { [weak self] error in
            self?.showError()
        }
    }

    private func showError() {
        let alertAction = UIAlertAction(title: Launch.Constant.confirmationButton, style: .default) { _ in
            self.alertController?.dismiss(animated: true, completion: nil)
        }
        alertController = UIAlertController(title: Launch.Constant.alertTitle, message: Launch.Constant.alertBody, preferredStyle: .alert)
        alertController?.addAction(alertAction)
        guard let alertController = alertController else { return }
        present(alertController, animated: true)
    }
}

extension LaunchViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.model.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: Launch.LaunchCell.launchCell.rawValue, for: indexPath) as? LaunchCell {
            cell.configureCell(model: model[indexPath.row])
            return cell
        }
        return UITableViewCell()
    }
}

extension LaunchViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let modelSelected = model[indexPath.row]
        //TODO: Navigate to Next View
    }
}

Bonus: migration du code à MVP architecture