Как реализовать простой шаблон проектирования MVC в Swift? - PullRequest
0 голосов
/ 26 февраля 2019

Я новичок в модели проектирования MVC.Я создал «DataModel», он будет выполнять вызов API, создавать данные и возвращать данные в ViewController, используя делегирование и «DataModelItem», который будет содержать все данные. Как вызвать функцию инициализации DataModel в функции "requestData" .Вот мой код:

protocol DataModelDelegate:class {
    func didRecieveDataUpdata(data:[DataModelItem])
    func didFailUpdateWithError(error:Error)
}

class DataModel: NSObject {
    weak var delegate : DataModelDelegate?
    func requestData() {

    }
    private func setDataWithResponse(response:[AnyObject]){
        var data = [DataModelItem]()
        for item in response{
            if let tableViewModel = DataModelItem(data: item as? [String : String]){
                data.append(tableViewModel)
            }
        }
        delegate?.didRecieveDataUpdata(data: data)
    }
}

А для DataModelItem:

class DataModelItem{
    var name:String?
    var id:String?

    init?(data:[String:String]?) {
        if let data = data, let serviceName = data["name"] , let serviceId = data["id"] {
            self.name = serviceName
            self.id = serviceId
        }
        else{
            return nil
        }
    }
}

Контроллер:

class ViewController: UIViewController {
    private let dataSource = DataModel()
    override func viewDidLoad() {
        super.viewDidLoad()
        dataSource.delegate = self
    }

    override func viewWillAppear(_ animated: Bool) {
        dataSource.requestData()
    }

}
extension ViewController : DataModelDelegate{
    func didRecieveDataUpdata(data: [DataModelItem]) {
        print(data)
    }

    func didFailUpdateWithError(error: Error) {
        print("error:  \(error.localizedDescription)")
    }


}

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

Как реализовать простой шаблон проектирования MVC в Swift?

Как общий ответ, в разработке для iOS вы уже делаете это неявно!Работа с раскадровкой (-ями) подразумевает слой view , а управление логикой того, как они работают и как они подключены к модели , осуществляется путем создания контроллера представления это поток по умолчанию.

Для вашего случая давайте уточним точку, которая: согласно стандартному MVC, по умолчанию ответственным уровнем для вызова API должен быть - логически - контроллер представления.Однако в целях модульности, повторного использования и избегания создания массивных контроллеров представлений мы можем следовать подходу, который вы имитируете, но это не значит, что это ответственность модели, мы можем считать его вторичным вспомогательным уровнем (например, MVC-N).), что означает (в зависимости от вашего кода): DataModel - это , а не модель, это «сетевой» уровень, а DataModelItem - фактическая модель.


Как вызвать функцию инициализации DataModel в функции "requestData"

Мне кажется, что она не создает сцены.Вместо этого вам нужен экземпляр из DataModel, поэтому вы можете вызвать нужный метод.

В контроллере вида:

let object = DataModel()
object.delegate = self // if you want to handle it in the view controller itself
object.requestData()
0 голосов
/ 08 марта 2019

Я просто делюсь своим ответом здесь и использую кодируемый.Это будет полезно для всех:

Модель :

import Foundation

struct DataModelItem: Codable{
    struct Result : Codable {
        let icon : String?
        let name : String?
        let rating : Float?
        let userRatingsTotal : Int?
        let vicinity : String?

        enum CodingKeys: String, CodingKey {
            case icon = "icon"
            case name = "name"
            case rating = "rating"
            case userRatingsTotal = "user_ratings_total"
            case vicinity = "vicinity"
        }
    }
    let results : [Result]?
}

Сетевой уровень :

import UIKit

protocol DataModelDelegate:class {
    func didRecieveDataUpdata(data:[String])
    func didFailUpdateWithError(error:Error)
}

class DataModel: NSObject {
    weak var delegate : DataModelDelegate?
    var theatreNameArray = [String]()
    var theatreVicinityArray = [String]()
    var theatreiconArray = [String]()
    func requestData() {
        Service.sharedInstance.getClassList { (response, error) in
            if error != nil {
                self.delegate?.didFailUpdateWithError(error: error!)
            } else if let response = response{
                self.setDataWithResponse(response: response as [DataModelItem])
            }
        }
    }

    private func setDataWithResponse(response:[DataModelItem]){
        for i in response[0].results!{
            self.theatreNameArray.append(i.name!)
            self.theatreVicinityArray.append(i.vicinity!)
            self.theatreiconArray.append(i.icon!)

        }
        delegate?.didRecieveDataUpdata(data: theatreNameArray)
        print("TheatreName------------------------->\(self.theatreNameArray)")
        print("TheatreVicinity------------------------->\(self.theatreVicinityArray)")
        print("Theatreicon------------------------->\(self.theatreiconArray)")

    }
}

Контроллер :

class ViewController: UIViewController {
    private let dataSource = DataModel()
    override func viewDidLoad() {
        super.viewDidLoad()
        dataSource.delegate = self
    }

    override func viewWillAppear(_ animated: Bool) {
        dataSource.requestData()
    }

}
extension ViewController : DataModelDelegate{
    func didRecieveDataUpdata(data: [DataModelItem]) {
        print(data)
    }

    func didFailUpdateWithError(error: Error) {
        print("error:  \(error.localizedDescription)")
    }


}

APIManager :

class Service : NSObject{
    static let sharedInstance = Service()    
    func getClassList(completion: (([DataModelItem]?, NSError?) -> Void)?) {
        guard let gitUrl = URL(string: "") else { return }
        URLSession.shared.dataTask(with: gitUrl) { (data, response
            , error) in
            guard let data = data else { return }
            do {
                let decoder = JSONDecoder()
                let gitData = try decoder.decode(DataModelItem.self, from: data)
                completion!([gitData],nil)

            } catch let err {
                print("Err", err)
                completion!(nil,err as NSError)
            }
            }.resume()
    }
}
0 голосов
/ 26 февраля 2019

Я бы порекомендовал использовать экземпляр Singleton для DataModel, поскольку это будет класс, который вы будете вызывать из многих точек вашего приложения.Вы можете обратиться к его документации по адресу: Управление общими ресурсами с помощью singleton При этом вам не нужно будет инициализировать этот экземпляр класса каждый раз, когда вам потребуется доступ к данным.

...