2017-05-14 17 views
0

JSONデータをテーブルビューに入れて、forループを使用してデータを解析しようとしています。ただし、ループがJSONデータを解析して20項目をテーブルビューに配置すると、プロセスが再起動され、JSONが再び解析され、同じデータが再びテーブルビューに表示されます。このプロセスは長い間繰り返されます。forループは、条件が完了してもJSONを繰り返し解析し続けます。

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Do any additional setup after loading the view. 

    locationManager.delegate = self 
    locationManager.requestWhenInUseAuthorization() 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.startUpdatingLocation() 

} 

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

    guard let location = locations.last else{ return } 

    var searchURL = NSString(format: "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=%f,%f&radius=50000&types=night_club&key=MY_API_KEY", (location.coordinate.latitude),(location.coordinate.longitude)) as? String 

    var cityInfo = NSString(format: "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=%f,%f&radius=50000&types=locality&key=MY_API_KEY", (location.coordinate.latitude),(location.coordinate.longitude)) as? String 

    manager.stopUpdatingLocation() 
    getCityInfo(url: cityInfo!) 
    callAlamo(url: searchURL!) 
} 

func getCityInfo(url:String){ 

    Alamofire.request(url).responseJSON(completionHandler: { response in 

     self.parseJSON(JSONData: response.data!) 
    }) 
} 

func parseJSON(JSONData:Data){ 

    do{ 

     var readableJSON = try JSONSerialization.jsonObject(with: JSONData) as! JSONStandard 

     // PARSING THROUGH JSON DATA TO GET CITY NAME 

     if let results = readableJSON["results"] as? [JSONStandard]{ 
      for i in 0..<results.count{ 

       let item = results[i] 
       let cityInfo = item["name"] as! String 
       cityName.append(cityInfo) 

       // GETTING PHOTO URL WITH photo_reference AND PUTTING THEM INTO imageURL ARRAY 

       if let photos = item["photos"] as? [JSONStandard]{ 

        for j in 0..<photos.count{ 

         let photo = photos[j] as JSONStandard 

         let photoRef = photo["photo_reference"] as! String 

         let photoURL = NSString(format: "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=%@&key=MY_API_KEY", photoRef) as? String 
         cityURL.append(photoURL!) 
        } 
       } 
      } 
     } 
     cityLabel.text = cityName[0] 
     cityImage.sd_setImage(with: URL(string:cityURL[0]), placeholderImage: #imageLiteral(resourceName: "cityOfCalgary")) 
    } 
    catch{ 
     print(error) 
    } 
} 

func callAlamo(url:String){ 

    Alamofire.request(url).responseJSON(completionHandler: { response in 

     self.parseData(JSONData: response.data!) 
    }) 
} 
func parseData(JSONData:Data){ 

    do{ 
     var myReadableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! JSONStandard 

     // PARSING THROUGH JSON DATA TO GET NAMES AND PICTURES OF PLACES, THEN PUTTING 
     // THEM INTO AN ARRAY AND OUTPUTTING THEM ONTO TABLE VIEW CELL 

     if let results = myReadableJSON["results"] as? [JSONStandard]{ 

      for i in 0..<results.count{ //results.count = 20 

       let item = results[i] 
       let names = item["name"] as! String 

       placeNames.append(names) 

       // GETTING PHOTO URL WITH photo_reference AND PUTTING THEM INTO imageURL ARRAY 

       if let photos = item["photos"] as? [JSONStandard]{ 

        let photoRef = photos[0] 
        let photoReference = photoRef["photo_reference"] as! String 


        let photoURL = NSString(format: "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=%@&key=MY_API_KEY", photoReference) as? String 

        imageURL.append(photoURL!) 

       } 

       if let geometry = item["geometry"] as? JSONStandard{ 
        if let location = geometry["location"] as? [String : Any]{ 

          let latitude = location["lat"] as? Double 
          let longitude = location["lng"] as? Double 
        } 
       } 
      } 
     } 
       // SHOULD BE PLACED AT THE END OF GATHERING DATA 
       locationManager.stopUpdatingLocation() 
       self.tableView.reloadData() 
    } 
    catch{ 
     print(error) 
    } 
} 

UPDATE:

ヴァディアンは、彼の最初のコメントの一つに言及したとおり、parseData()が複数回呼び出さなっていました。私はlocationManagerデリゲート機能に場所の更新を停止した後、だから私は

locationManager.delegate = nilの

を追加しました。

`  

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

    guard let location = locations.last else{ return } 

    searchURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=\(location.coordinate.latitude),\(location.coordinate.longitude)&radius=50000&types=night_club&key=MY_API_KEY" 

    cityInfo = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=\(location.coordinate.latitude),\(location.coordinate.longitude)&radius=50000&types=locality&key=MY_API_KEY" 

    locationManager.stopUpdatingLocation() 
    locationManager.delegate = nil 

    getCityInfo(url: cityInfo) 
    callAlamo(url: searchURL) 
} 

`

他のすべては、この後も同じまま。

+0

'parseData'が2回呼び出されたと思いますが、コードはメソッドで繰り返されません。 Swiftではいつも '.mutableContainers'が無意味なので、' options'パラメータを省略し、醜いCスタイルのインデックスループの代わりに '結果の中のitemに対して'高速列挙を使います。 – vadian

+0

PS:ループの各繰り返しでテーブルビューをリロードしないでください。リピートループの後に 'stopUpdatingLocation()' - **を加えてください。 – vadian

+0

コメントとヒントをありがとう。 parseDataを呼び出すメソッドを表示するために、私が行った提案の一部を反映するようにコードを更新しました。残念ながら、私はまだ同じ問題を抱えています。 – notSoExperiencedCoder

答えて

0

parseDataを複数回呼び出すと思われました。解決策は、デリゲートメソッドで正しい場所の監視を停止することです。

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

    guard let location = locations.last else { return } 

    let searchURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=\(location.coordinate.latitude),\(location.coordinate.longitude)&radius=50000&types=night_club&key=AIzaSyA2LQsGK_I1ETnKPGbjWgFW9onZlHog6dg" 

    // var cityInfo = NSString(format: "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=%f,%f&radius=50000&types=locality&key=AIzaSyA2LQsGK_I1ETnKPGbjWgFW9onZlHog6dg", (location?.coordinate.latitude)!,(location?.coordinate.longitude)!) as? String 
    manager.stopUpdatingLocation() 
    callAlamo(url: searchURL) 
} 

すべての質問と感嘆符を避けるために、メソッドの本体を少し編集しました。

サイドノート:基本的にはありませんコンパイラが推論できるアノテートタイプです。

+0

提案した内容を実装しましたが、同じ問題が続く=( 私のコードを更新しました – notSoExperiencedCoder

関連する問題