Невозможно получить данные в цикле с сервера в Swift4

#ios #swift4 #alamofire

#iOS #swift4 #alamofire

Вопрос:

Я пытаюсь получить данные, такие как широта и долгота, с сервера, используя сетевую библиотеку Alamofire 5 в своем приложении, и хочу отобразить данные на карте Google в качестве маркера.Я могу успешно получить данные с сервера, но проблема в том, что они не отображаются на карте в качестве маркера, когда я повторяю данные с помощью цикла for.

Ниже приведен мой код для извлечения данных с сервера:

 func LocationApiData(){
let params = ["latitude":"28.4185599", "longitude":"77.0377506","cus_id":"CUS_000020","cat_id":cat_id,"city":"gurugram","sub_cat_id_1":"","sub_cat_id_2":"","radius":"5"]
AF.request(Urls.LocationUpdateUrl,method: .post,parameters: params).response { response in
       if let Data = response.data {
           do{
               let userResponse = try JSONDecoder().decode(UpdateLocationModel .self, from: Data)
            self.locationArr.append(contentsOf: userResponse.fixdata!)
               print(userResponse)
               
               DispatchQueue.main.async {
                   self.SliderCollection.reloadData()
               }
           }catch let err{
               print(err.localizedDescription)
           }
       }
    }
 }
  

В приведенном выше коде я передаю данные в пустой массив с именем locationArr с именем класса модели fixdata, который является подклассом UpdateLocationModel.

 import Foundation
struct UpdateLocationModel : Codable {
let fix_status : String?
let set_timer : String?
let notified_maxtimer : String?
let fixdata : [Fixdata]?
let moving_status : String?
let message : String?
let movingdata : [String]?

enum CodingKeys: String, CodingKey {

    case fix_status = "fix_status"
    case set_timer = "set_timer"
    case notified_maxtimer = "notified_maxtimer"
    case fixdata = "fixdata"
    case moving_status = "Moving_status"
    case message = "message"
    case movingdata = "Movingdata"
}

init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    fix_status = try values.decodeIfPresent(String.self, forKey: .fix_status)
    set_timer = try values.decodeIfPresent(String.self, forKey: .set_timer)
    notified_maxtimer = try values.decodeIfPresent(String.self, forKey: .notified_maxtimer)
    fixdata = try values.decodeIfPresent([Fixdata].self, forKey: .fixdata)
    moving_status = try values.decodeIfPresent(String.self, forKey: .moving_status)
    message = try values.decodeIfPresent(String.self, forKey: .message)
    movingdata = try values.decodeIfPresent([String].self, forKey: .movingdata)
   }

}
struct Fixdata : Codable {
let name : String?
let mobile_no : String?
let business_mobile_no : String?
let image_url : String?
let image_cat_url : String?
let menu_status : String?
let fix_url : String?
let cat_data : String?
let show_status : String?
let average_rating : String?
let latitude : String?
let hawker_code : String?
let longitude : String?
let distance : Double?
let user_type : String?
let cus_id : String?
let status : String?

enum CodingKeys: String, CodingKey {

    case name = "name"
    case mobile_no = "mobile_no"
    case business_mobile_no = "business_mobile_no"
    case image_url = "image_url"
    case image_cat_url = "image_cat_url"
    case menu_status = "menu_status"
    case fix_url = "fix_url"
    case cat_data = "cat_data"
    case show_status = "Show_status"
    case average_rating = "average_rating"
    case latitude = "latitude"
    case hawker_code = "hawker_code"
    case longitude = "longitude"
    case distance = "distance"
    case user_type = "user_type"
    case cus_id = "cus_id"
    case status = "status"
}

init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    name = try values.decodeIfPresent(String.self, forKey: .name)
    mobile_no = try values.decodeIfPresent(String.self, forKey: .mobile_no)
    business_mobile_no = try values.decodeIfPresent(String.self, forKey: .business_mobile_no)
    image_url = try values.decodeIfPresent(String.self, forKey: .image_url)
    image_cat_url = try values.decodeIfPresent(String.self, forKey: .image_cat_url)
    menu_status = try values.decodeIfPresent(String.self, forKey: .menu_status)
    fix_url = try values.decodeIfPresent(String.self, forKey: .fix_url)
    cat_data = try values.decodeIfPresent(String.self, forKey: .cat_data)
    show_status = try values.decodeIfPresent(String.self, forKey: .show_status)
    average_rating = try values.decodeIfPresent(String.self, forKey: .average_rating)
    latitude = try values.decodeIfPresent(String.self, forKey: .latitude)
    hawker_code = try values.decodeIfPresent(String.self, forKey: .hawker_code)
    longitude = try values.decodeIfPresent(String.self, forKey: .longitude)
    distance = try values.decodeIfPresent(Double.self, forKey: .distance)
    user_type = try values.decodeIfPresent(String.self, forKey: .user_type)
    cus_id = try values.decodeIfPresent(String.self, forKey: .cus_id)
    status = try values.decodeIfPresent(String.self, forKey: .status)
   }

}
  

Теперь у меня возникает проблема, я не могу отобразить маркер на карте на основе данных, которые я получил с сервера.Здесь в приведенном ниже коде locationArr есть данные, но когда я пытаюсь выполнить итерацию в методе markerShow(), данные не отображаются, и у меня также есть отладочный код, но он не компилируется после for places in locationArr строки.

 func markerShow(){
    
    for places in locationArr {
    let marker = GMSMarker()
    // I have taken a pin image which is a custom image
    let markerImage = UIImage(named: "app_logo_customer")!
    //creating a marker view
    let markerView = UIImageView(image: markerImage)
    let lat = Double(places.latitude!)
    let long = Double(places.longitude!)
    marker.position = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
    marker.title = "New Delhi"
    marker.snippet = "India"
    marker.map = googleMaps
        
        
    let link = places.image_cat_url!
  //  markerView.sd_setImage(with: URL(string:link ), placeholderImage: markerImage)
  //  marker.iconView = markerView

        
    // this sdwebimage task url binding
    let imageUrl:NSURL? = NSURL(string: link)
        if let url = imageUrl {
            markerView.sd_setImage(with: url as URL, completed: nil)
            marker.iconView = markerView
        }
        
    }
}
  

Кто-нибудь, пожалуйста, дайте мне знать, что я делаю не так. Любая помощь будет оценена.

Спасибо

Комментарии:

1. Куда вы звоните markerShow ? Скорее всего, вы вызываете его до завершения асинхронной сетевой операции

2. в методе viewDidLoad

3. Вы должны отредактировать свой вопрос, чтобы показать этот код, но вы не можете вызвать его напрямую, viewDidLoad поскольку, предположительно, вы также вызываете LocationApiData там, и данные еще не будут извлечены, когда вы попытаетесь добавить маркеры. Вам необходимо передать закрытие обработчика завершения вашей функции загрузки, чтобы вы могли добавить маркеры после завершения сетевой операции.