2017-10-18 3 views
0

J'utilise Google Maps et l'API Google et je suis en train de charger des endroits à proximité dans un tableView mais chaque fois que je viens dans cette classeprovideAPIKey: devrait être appelé au plus une fois (Swift)

import UIKit 
import MapKit 
import CoreLocation 
import GoogleMaps 
import GooglePlaces 
import Social 
import AVFoundation 


private let resueIdentifier = "MyTableViewCell" 


extension UIViewController { 
    func present(viewController : UIViewController, completion : (() ->())? = nil){ 
     if let presented = self.presentedViewController { 
      presented.dismiss(animated: true, completion: { 
       self.present(viewController, animated: true, completion: completion) 
      }) 
     } else { 
      self.present(viewController, animated: true, completion: completion) 
     } 
    } 
} 


class CourseClass2: UIViewController, UITableViewDelegate, UITableViewDataSource { 





    @IBOutlet weak var tableView: UITableView! 




    struct User { 

     var name: String 
     var images: UIImage 
     var type: String 

    } 


    var previuosViewTappedButtonsArray = [String]() 
    var locationManager:CLLocationManager? 
    let minimumSpacing : CGFloat = 15 //CGFloat(MAXFLOAT) 
    let cellWidth: CGFloat = 250 
    let radius = 5000 // 5km 
    var category : QCategoryy? 
    var currentLocation : CLLocationCoordinate2D? 
    var places: [QPlace] = [] 
    var isLoading = false 
    var response : QNearbyPlacesResponse? 
    var rows = 0 
    var users = [User]() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.title = category?.name 

} 


    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 

     determineMyCurrentLocation() 
    } 

    override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
    } 



    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 

     rows = 0 
     insertRowsMode3() 
     tableView.reloadData() 
     category?.markView() 

} 




    @IBAction func refreshTapped(_ sender: Any) { 

     rows = 0 
     insertRowsMode3() 
     tableView.reloadData() 
    } 




    func canLoadMore() -> Bool { 
     if isLoading { 
      return false 
     } 

     if let response = self.response { 
      if (!response.canLoadMore()) { 
       return false 
      } 
     } 

     return true 
    } 

    func loadPlaces(_ force:Bool) { 

     if !force { 
      if !canLoadMore() { 
       return 
      } 
     } 

     print("load more") 
     isLoading = true 
     NearbyPlaces.getNearbyPlaces(by: category?.name ?? "food", coordinates: currentLocation!, radius: radius, token: self.response?.nextPageToken, completion: didReceiveResponse) 
    } 



    func didReceiveResponse(response:QNearbyPlacesResponse?, error : Error?) -> Void { 
     if let error = error { 
      let alertController = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert) 
      let actionDismiss = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil) 
      let actionRetry = UIAlertAction(title: "Retry", style: .default, handler: { (action) in 
       DispatchQueue.main.async { 
        self.loadPlaces(true) 
       } 
      }) 
      alertController.addAction(actionRetry) 
      alertController.addAction(actionDismiss) 
      DispatchQueue.main.async { 
       self.present(viewController: alertController) 

      } 
     } 
     if let response = response { 
      self.response = response 
      if response.status == "OK" { 
       if let placesDownloaded = response.places { 
        places.append(contentsOf: placesDownloaded) 
       } 

       self.tableView?.reloadData() 
      } else { 
       let alert = UIAlertController.init(title: "Error", message: response.status, preferredStyle: .alert) 
       alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil)) 
       alert.addAction(UIAlertAction.init(title: "Retry", style: .default, handler: { (action) in 
        DispatchQueue.main.async { 
         self.loadPlaces(true) 
        } 
       })) 
       self.present(viewController: alert) 
      } 
      isLoading = false 
     } 
     else { 
      print("response is nil") 
     } 
    } 















    func insertRowsMode2() { 

     tableView.beginUpdates() 
     for i in 0..<places.count { 
      insertRowMode2(ind: i, usr: places[i]) 
     } 
     tableView.endUpdates() 
    } 

    func insertRowMode2(ind:Int,usr:QPlace) { 
     tableView.beginUpdates() 
     let indPath = IndexPath(row: ind, section: 0) 

     rows = ind + 1 
     tableView.insertRows(at: [indPath], with: .right) 
     tableView.endUpdates() 
    } 



    func insertRowsMode3() { 
     tableView.beginUpdates() 
     rows = 0 

     insertRowMode3(ind: 0) 
     tableView.endUpdates() 
    } 




    func insertRowMode3(ind:Int) { 
     tableView.beginUpdates() 
     let indPath = IndexPath(row: ind, section: 0) 
     rows = ind + 1 
     tableView.insertRows(at: [indPath], with: .right) 

     guard ind < places.count-1 else { return } 
     DispatchQueue.main.asyncAfter(deadline: .now()+0.20) { 

      self.insertRowMode3(ind: ind+1) 
     } 
     tableView.endUpdates() 
    } 





    func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 





    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return places.count /* rows */ 
    } 



    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell 


     let place = places[indexPath.row] 
     cell.update(place: place) 

     if indexPath.row == places.count - 1 { 
      loadPlaces(false) 
     } 



     /* let user = users[indexPath.row] 

     cell.selectionStyle = .none 
     cell.myImage.image = user.images 
     cell.myLabel.text = user.name 
     cell.myTypeLabel.text = user.type */ 

     return (cell) 
    } 




    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 

     tableView.deselectRow(at: indexPath, animated: true) 

     UIView.animate(withDuration: 0.2, animations: { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell 
    }) 

     performSegue(withIdentifier: "goToLast" , sender: users[indexPath.row]) 
    } 




    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     return 100 
    } 




    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 




    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 

     if editingStyle == UITableViewCellEditingStyle.delete { 

      places.remove(at: indexPath.row) 
      tableView.deleteRows(at: [indexPath], with: .fade) 

     } 

    } 









    func didReceiveUserLocation(_ userLocation:CLLocation) { 
     currentLocation = userLocation.coordinate 

     loadPlaces(true) 
    } 

















    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     if segue.identifier == "goToLast" && sender is IndexPath { 


      let dvc = segue.destination as! FinalClass 
      dvc.index = (sender as! IndexPath).row 
      dvc.places = places 
      dvc.userLocation = currentLocation 





      /* guard let vc = segue.destination as? FinalClass else { return } 

      let guest = segue.destination as! FinalClass 

      if let user = sender as? User { 
      */ 

      } 
     } 




    @IBAction func IndTapped(_ sender: Any) { 
    dismiss(animated: true, completion: nil) 

    } 




    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 



































    @IBAction func socialShare(_ sender: Any) { 


     //Alert 
     let alert = UIAlertController(title: "Share", message: "First share!", preferredStyle: .actionSheet) 

     //First action 
     let actionOne = UIAlertAction(title: "Share on Facebook", style: .default) { (action) in 

      //Checking if user is connected to Facebook 
      if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeFacebook) 
      { 
       let post = SLComposeViewController(forServiceType: SLServiceTypeFacebook)! 

       post.setInitialText("First") 
       post.add(UIImage(named: "uround logo.png")) 

       self.present(post, animated: true, completion: nil) 

      } else {self.showAlert(service: "Facebook")} 

     } 

     let actionThree = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) 

     //Add action to action sheet 
     alert.addAction(actionOne) 

     alert.addAction(actionThree) 

     //Present alert 
     self.present(alert, animated: true, completion: nil) 

    } 



    func showAlert(service:String) 
    { 
     let alert = UIAlertController(title: "Error", message: "You are not connected to \(service)", preferredStyle: .alert) 
     let action = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil) 

     alert.addAction(action) 
     present(alert, animated: true, completion: nil) 
    } 









} 





extension CourseClass2: CLLocationManagerDelegate { 

    func determineMyCurrentLocation() { 
     locationManager = CLLocationManager() 
     locationManager?.delegate = self 
     locationManager?.desiredAccuracy = kCLLocationAccuracyBest 
     locationManager?.requestWhenInUseAuthorization() 
    } 

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
     let userLocation:CLLocation = locations[0] as CLLocation 

     manager.stopUpdatingLocation() 

     print("user latitude = \(userLocation.coordinate.latitude)") 
     print("user longitude = \(userLocation.coordinate.longitude)") 

     didReceiveUserLocation(userLocation) 
    } 

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { 
     print("Error \(error)") 
     errorGettingCurrentLocation(error.localizedDescription) 
    } 

    public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 
     if status == .authorizedWhenInUse || status == .authorizedAlways { 
      locationManager?.startUpdatingLocation() 
      //locationManager.startUpdatingHeading() 
     } else if status == .denied || status == .restricted { 
      errorGettingCurrentLocation("Location access denied") 
     } 
    } 

    func errorGettingCurrentLocation(_ errorMessage:String) { 
     let alert = UIAlertController.init(title: "Error", message: errorMessage, preferredStyle: .alert) 
     alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil)) 
     present(alert, animated: true, completion: nil) 
} 
} 

i le message « erreur - état de réponse » de cette fonction

func didReceiveResponse(response:QNearbyPlacesResponse?, error : Error?) -> Void { 
     if let error = error { 
      let alertController = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert) 
      let actionDismiss = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil) 
      let actionRetry = UIAlertAction(title: "Retry", style: .default, handler: { (action) in 
       DispatchQueue.main.async { 
        self.loadPlaces(true) 
       } 
      }) 
      alertController.addAction(actionRetry) 
      alertController.addAction(actionDismiss) 
      DispatchQueue.main.async { 
       self.present(viewController: alertController) 

      } 
     } 
     if let response = response { 
      self.response = response 
      if response.status == "OK" { 
       if let placesDownloaded = response.places { 
        places.append(contentsOf: placesDownloaded) 
       } 

       self.tableView?.reloadData() 
      } else { 
       let alert = UIAlertController.init(title: "Error", message: response.status, preferredStyle: .alert) 
       alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil)) 
       alert.addAction(UIAlertAction.init(title: "Retry", style: .default, handler: { (action) in 
        DispatchQueue.main.async { 
         self.loadPlaces(true) 
        } 
       })) 
       self.present(viewController: alert) 
      } 
      isLoading = false 
     } 
     else { 
      print("response is nil") 
     } 
    } 

si regardant dans la console j'ai vu cette erreur « ((null)) était faux: provideAPIKey: devrait être appelé au plus une fois », qui est peut-être le cause du problème (même si je ne suis pas sûr), j'ai suivi le guide de documentation google pour obtenir la clé API pour le projet ect, voici mon appDelegate où il y a mes clés (je l'ai changé pour l'instant les chiffres de la clé avec « Ma clé api »)

import UIKit 
import Firebase 
import CoreLocation 
import GoogleMaps 
import GooglePlaces 
import FBSDKCoreKit 
import GoogleSignIn 
import FBSDKShareKit 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate { 

    static let googleMapsApiKey = "MY API Key" 
    static let googlePlacesAPIKey = "MY API Key" 

    var window: UIWindow? 
    var locationManager: CLLocationManager? 

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     // Override point for customization after application launch. 



     FirebaseApp.configure() 

     locationManager = CLLocationManager() 
     locationManager?.requestWhenInUseAuthorization() 
     GMSServices.provideAPIKey(AppDelegate.googleMapsApiKey) 
     GMSPlacesClient.provideAPIKey(AppDelegate.googlePlacesAPIKey) 


     FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) 

     IQKeyboardManager.sharedManager().enable = true 
     IQKeyboardManager.sharedManager().enableAutoToolbar = false 


     GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID 
     GIDSignIn.sharedInstance().delegate = self 

     if GMSServices.provideAPIKey("MY API Key") { 
      print("good provided keys correctly") 
     } 
     else { 
      print("key didn't provided") 
     } 

     return true 
    } 

quelqu'un peut dire si le problème est une mauvaise utilisation de la clé api ou si les clés sont fausses ou peut-être que le problème en est un autre?

Répondre

0

Regardez ce que vous faites ici:

// once 
GMSServices.provideAPIKey(AppDelegate.googleMapsApiKey) 
GMSPlacesClient.provideAPIKey(AppDelegate.googlePlacesAPIKey) 


FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) 

IQKeyboardManager.sharedManager().enable = true 
IQKeyboardManager.sharedManager().enableAutoToolbar = false 


GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID 
GIDSignIn.sharedInstance().delegate = self 
// twice! 
if GMSServices.provideAPIKey("MY API Key") { 

Vous appelez provideAPIKey deux fois!

Je sais que vous voulez vérifier si la clé API est fournie correctement, mais la manière correcte de le faire est de ne pas appeler la méthode deux fois. Au lieu de cela, vous devez stocker la valeur de retour et vérifier la valeur de retour:

// put the return value in "success" 
let success = GMSServices.provideAPIKey(AppDelegate.googleMapsApiKey) 
GMSPlacesClient.provideAPIKey(AppDelegate.googlePlacesAPIKey) 


FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) 

IQKeyboardManager.sharedManager().enable = true 
IQKeyboardManager.sharedManager().enableAutoToolbar = false 


GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID 
GIDSignIn.sharedInstance().delegate = self 
// check "success" 
if success { 
+0

ce travail est merci, mais je reçois toujours le message « errore - Demande refusée » quand je viens dans cette classe pour charger endroits à proximité, peut-être i peut essayer de régénérer les clés? – seran

+0

@seran Vous êtes très vague ici, et vous avez montré trop de code. Il faut beaucoup de temps pour parcourir tout votre code et savoir exactement où vous entendez par "cette classe" et "charger les lieux à proximité". En outre, je pense que cela sort du cadre de cette question. Je vous suggère d'essayer de localiser l'erreur et de réduire votre code en conséquence, puis de poster une nouvelle question. – Sweeper

+0

ok je vais faire comme ça – seran