Swift:为什么用户的位置在queryForTable方法中不可用?

时间:2016-01-14 22:22:13

标签: swift parse-platform core-location

我在我的应用中使用Swift,CoreLocation和Parse。我有几个问题,希望有人可以回答:

1) 何时调用queryForTable方法?

2)当应用加载时,为什么用户的当前位置(CLLocationCoordinate2D)无法从get get获取(currLocation起初似乎为零:if let queryLoc = currLocation)?

请参阅下面代码中的部分评论。

var currLocation: PFGeoPoint?

override func viewDidLoad() {
    super.viewDidLoad()

    queryForPosts()
}

func queryForPosts() {

    PFGeoPoint.geoPointForCurrentLocationInBackground {
        (geoPoint: PFGeoPoint?, error: NSError?) -> Void in
        if error == nil {
            // do something with the new geoPoint
            self.currLocation = geoPoint

            // this will call queryForTable
            self.loadObjects()
        }
    }

}

override func queryForTable() -> PFQuery {

    let query = PFQuery(className: ParseHelper.ParsePostClass)

    // Need to fix: the query is being run before the location manager returns a valid location (currLocation)...
    if let queryLoc = self.currLocation {

        print("SUCESS: Successfully queried user's location.")

        query.whereKey("location", nearGeoPoint: queryLoc, withinMiles: 3)

        query.limit = 200;

        if (self.objects?.count == 0) {

            query.cachePolicy = PFCachePolicy.CacheThenNetwork

        }

        query.addDescendingOrder("createdAt")

        return query

    } else {
        // This else block is being executed first every time the view loads. Only after the user performs a pull to refresh on the table view, the if block gets executed and the correct objects display. 
        print("FAILURE: Could not query user's location.")

        /* Decide on how the application should react if there is no location available */

    }

    return PFQuery()

}

2 个答案:

答案 0 :(得分:3)

该位置不可用,因为didUpdateLocations是一个异步过程。

startUpdatingLocation上的

From Apple's documentation

  

此方法立即返回。调用此方法会导致   位置管理器获取初始位置修复(可能需要   几秒钟)并通过调用它来通知你的代表   locationManager:didUpdateLocations:方法

正如gnasher729所述,手机的定位服务使用功耗密集型系统,一旦完成,应该禁用。您已使用locationManager.stopUpdatingLocation()实现此目的。

关于在PFQueryTableViewController中何时调用queryForTable的问题,我们所要做的就是look at the open-sourced ParseUI Github for it。我们在此处发现queryForTable被称为loadObjects的一部分,而后者又在viewDidLoad中调用。

您应该使用的是geoPointForCurrentLocationInBackgroundIncluded in the Parse framework),这样可以轻松获取用户的位置。如文档中所述,此功能会为您处理所有位置服务。

  
      
  • 内部CLLocationManager开始侦听位置更新   (通过startsUpdatingLocation)。
  •   
  • 收到位置后,即可   位置管理器停止侦听位置更新(通过   stopsUpdatingLocation)和PFGeoPoint是从新创建的   地点。如果位置管理器出错,它仍然会停止收听   用于更新,而是返回NSError。
  •   
  • 使用PFGeoPoint调用您的块。
  •   

在单独的函数中使用它并在viewDidLoad中调用它:

PFGeoPoint.geoPointForCurrentLocationInBackground {
  (geoPoint: PFGeoPoint?, error: NSError?) -> Void in
  if error == nil {
    // do something with the new geoPoint

    // this will call queryForTable
    self.loadObjects()
  }
}

答案 1 :(得分:1)

要获取用户的位置,设备必须打开一些相当耗电的系统。例如,GPS需要很多功率。如果GPS永久打开,您的用户会非常不满意。