Я рассмотрел подобный вопрос здесь, в stackoverflow, но ни одно из решений не работает для меня.
Я выполняю сетевой вызов и на основании ответа на вызов я выполню навигацию.Для правильного интерфейса мне нужно показать диалог загрузки, чтобы показать пользователю, что что-то происходит.Поскольку мой диалог загрузки будет использоваться несколько раз, поэтому я создал расширение, подобное этому
import UIKit
extension UIViewController {
func showLoadingDialog() {
var alertController: UIAlertController!
alertController = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
//alertController.view.tintColor = brownColor //UIColor.brown
let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50)) as UIActivityIndicatorView
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.white
loadingIndicator.color = UIColor.white
loadingIndicator.startAnimating()
alertController.view.addSubview(loadingIndicator)
alertController.view.subviews.first?.backgroundColor = UIColor.clear
present(alertController, animated: false, completion: nil)
}
func dismissLoader() {
dismiss(animated: false, completion: nil)
}
func showToast(controller: UIViewController, message : String, seconds: Double) {
let toastLabel = UILabel(frame: CGRect(x: 10, y: self.view.frame.size.height-100, width: self.view.frame.size.width-20, height: 50))
toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6)
toastLabel.textColor = UIColor.white
toastLabel.textAlignment = .center;
toastLabel.font = UIFont(name: "Montserrat-Light", size: 12.0)
toastLabel.text = message
toastLabel.numberOfLines = 2
toastLabel.alpha = 1.0
toastLabel.layer.cornerRadius = 10;
toastLabel.clipsToBounds = true
self.view.addSubview(toastLabel)
UIView.animate(withDuration: 3, delay: 1, options: .curveEaseOut, animations: {
toastLabel.alpha = 0.0
}, completion: {(isCompleted) in
toastLabel.removeFromSuperview()
})
}
}
Перед выполнением сетевого вызова я вызываю метод showLoadingDialog (), и когда я получаю ответ, я вызываю dismissLoader() метод, чтобы скрыть диалоговое окно загрузки, а затем на основе ответа я выполняю навигацию, как это
Это мой протокол просмотра, который реализуется моим контроллером
protocol ShipmentDetailsView: class {
func setShipmentResponse(shipmentResponse: ShipmentResponse)
func showErrorMessage(message: String)
func showProgressDialog()
func hideProgressDialog()
func getShipmentId() -> String
func navigateToLogin()
func onStatusCheckSuccess(shipmentResponse: ShipmentResponse)
}
Это мойКонтроллер ...
import UIKit
class ShipmentDetailsViewController: UIViewController, ShipmentDetailsView{
@IBOutlet weak var shipmentNumber: UILabel!
@IBOutlet weak var siteName: UILabel!
@IBOutlet weak var currentDestination: UILabel!
@IBOutlet weak var address: UILabel!
@IBOutlet weak var name: UILabel!
@IBOutlet weak var phoneNumber: UILabel!
@IBOutlet weak var startShipmentButton: UIButton!
var viewController: UIViewController!
var shipmentId: String = ""
var shipmentResponse: ShipmentResponse!
var presenter: IShipmentDetailsPresenter!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
hideKeyboard()
}
private func onCreate() {
presenter = ShipmentDetailsPresenter(view: self)
}
override func viewDidLoad() {
super.viewDidLoad()
onCreate()
}
@IBAction func startShipment(_ sender: Any) {
presenter.getShipmentByIdToCheckStatus(shipmentId: self.shipmentId)
}
public func setShipmentId(shipmentId: String) {
self.shipmentId = shipmentId
}
func navigateToLogin() {
//Todo
}
func onStatusCheckSuccess(shipmentResponse: ShipmentResponse) {
if shipmentResponse.Status == 0 {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let verifyViewController = storyboard.instantiateViewController(withIdentifier: "RunningShipmentViewController") as! RunningShipmentViewController
self.navigationController?.pushViewController(verifyViewController, animated: true)
} else {
showToast(controller: self, message: "Cannot start this shipment", seconds: 0.5)
}
}
func getShipmentId() -> String {
return self.shipmentId
}
func showErrorMessage(message: String) {
showToast(controller: self, message: message, seconds: 1.0)
}
func showProgressDialog() {
showLoadingDialog()
}
func hideProgressDialog() {
dismissLoader()
}
func setShipmentResponse(shipmentResponse: ShipmentResponse) {
self.shipmentResponse = shipmentResponse
updateUI(shipmentResponse: shipmentResponse)
}
private func updateUI(shipmentResponse: ShipmentResponse) {
if shipmentResponse.ShipmentNumber != "" {
self.shipmentNumber.text = shipmentResponse.ShipmentNumber
} else {
self.shipmentNumber.text = "-"
}
if shipmentResponse.SiteName != "" {
self.siteName.text = shipmentResponse.SiteName
} else {
self.siteName.text = "-"
}
if shipmentResponse.DestinationName != "" {
self.currentDestination.text = shipmentResponse.DestinationName
} else {
self.currentDestination.text = "-"
}
if shipmentResponse.SiteAddress != "" {
self.address.text = shipmentResponse.SiteAddress
} else {
self.address.text = "-"
}
if shipmentResponse.OrgResponsiblePersonName != "" {
self.name.text = shipmentResponse.OrgResponsiblePersonName
} else {
self.name.text = "-"
}
if shipmentResponse.OrgResponsiblePersonPhone != "" {
self.phoneNumber.text = shipmentResponse.OrgResponsiblePersonPhone
} else {
self.phoneNumber.text = "-"
}
}
}
Это мой код докладчика:
class ShipmentDetailsPresenter : IShipmentDetailsPresenter, ILoadShipmentInteractorOutput {
var view: ShipmentDetailsView!
var loadShipmentInteractor : ILoadShipmentInteractor!
init(view: ShipmentDetailsView) {
self.view = view
}
func getShipmentByIdToCheckStatus(shipmentId: String) {
view.showProgressDialog()
let queryString = NSString(format:Queries.SELECT_SHIPMENT_BY_ITEM_ID_QUERY as NSString, shipmentId)
loadShipmentInteractor = LoadShipmentInteractor(loadShipmentInteractorOutput: self)
loadShipmentInteractor.getShipmentByItemIdToCheckStatus(queryString: queryString as String)
}
func onGetShipmentByItemIdToCheckStatus(response: BaseResponse) {
view.hideProgressDialog()
if response.statusCode == 200 {
if let json = response.response.data(using: .utf8){
guard let obj = try? JSONDecoder().decode(ShipmentsResponse.self, from: json) else {return}
if obj.StatusCode == 0 && obj.TotalRecordCount>0 {
view.onStatusCheckSuccess(shipmentResponse: obj.Results[0])
} else {
//Todo
}
} else {
let errMessage = NSLocalizedString("error_parsing_response", comment: "Message to show if parsing went wrong")
print(errMessage)
}
} else if response.statusCode == 400 {
view.showErrorMessage(message: Messages.SESSION_EXPIRED_MESSAGE)
view.navigateToLogin()
} else {
view.showErrorMessage(message: Messages.SOMETHING_WENT_WRONG_MESSAGE)
//view.navigateToLogin()
}
}
}
Вот мой интерактор:
import Alamofire
class LoadShipmentInteractor : ILoadShipmentInteractor {
var loadShipmentInteractorOutput : ILoadShipmentInteractorOutput!
init(loadShipmentInteractorOutput : ILoadShipmentInteractorOutput) {
self.loadShipmentInteractorOutput = loadShipmentInteractorOutput
}
func getShipmentByItemIdToCheckStatus(queryString: String) {
let accessToken : String = UserDefaultsUtil.getAccessToken()
let url = ""+HttpRequestURLs.DATA_CORE_GET_FILTER
let headers = [
"Content-Type": Constatns.CONTENT_TYPE_JSON,
"Authorization": "bearer "+accessToken
]
let parameters = ["Text":queryString] as [String : Any]
Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseString {
response in
let statusCode = response.response?.statusCode as! Int
let re = response.result.value as! String
//print(re)
let baseResponse = BaseResponse()
baseResponse.statusCode = statusCode
baseResponse.response = re
self.loadShipmentInteractorOutput.onGetShipmentByItemIdToCheckStatus(response: baseResponse)
}
}
}