提供APIKey:应该最多调用一次(Swift)

时间:2017-10-18 09:39:52

标签: ios swift xcode google-maps swift3

我正在使用谷歌地图并放置API,我正试图在tableView中加载附近的地方,但每次我进入这个类

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)
}
}

我从此函数

收到消息“错误 - 响应状态”
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")
        }
    }

所以在控制台中看到我看到这个错误“((null)”是假的:provideAPIKey:应该最多调用一次“这可能是问题的原因(即使我不确定),我跟着获取项目API密钥的google文档指南,这里是我的appDelegate,其中有我的密钥(我现在更改了“My Api key”密钥的编号)

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
    }

有人可以判断问题是否是错误使用api密钥,或者密钥是错误还是问题可能是另一个?

1 个答案:

答案 0 :(得分:0)

看看你在这做什么:

// 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") {

您正在拨打provideAPIKey两次!

我知道您要检查是否正确提供了API密钥,但正确的方法是不要两次调用该方法。相反,您应该存储返回值并检查返回值:

// 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 {