gpt4 book ai didi

ios - 重大位置变化不会在设备上触发

转载 作者:可可西里 更新时间:2023-11-01 03:27:38 26 4
gpt4 key购买 nike

我正在使用重要的位置变化监控。当我在模拟器中运行代码并选中高速公路选项时,我会定期更新位置。我获取这些更新并将它们保存在 NSUserDefaults 中,而不是每 10 秒更新一次 tableview,这样我就可以查看是否有任何更新。如果我在真实设备上运行该应用程序,我将获得零更新。我 Handlebars 机放在口袋里,走了 80 多公里,去过 2 个城市。零更新。不确定我是否搞砸了。我附上代码。代码是复制粘贴的,欢迎测试。只需确保在 Storyboard 中使用 TableViewController 并将单元格 ID 设置为 ID。我错过了什么?我在 iPhone 5 上测试。

信息.plist:

enter image description here

编辑:在苹果文档中找到这个。我的 locationManager 是否应该以不同的方式创建?

When an app is relaunched because of a location update, the launch options dictionary passed to your application:willFinishLaunchingWithOptions: or application:didFinishLaunchingWithOptions: method contains the UIApplicationLaunchOptionsLocationKey key. The presence of that key signals that new location data is waiting to be delivered to your app. To obtain that data, you must create a new CLLocationManager object and restart the location services that you had running prior to your app’s termination. When you restart those services, the location manager delivers all pending location updates to its delegate.

编辑2:

基于此,位置应至少每 15 分钟更新一次。我的代码中的错误已确认。

If GPS-level accuracy isn’t critical for your app and you don’t need continuous tracking, you can use the significant-change location service. It’s crucial that you use the significant-change location service correctly, because it wakes the system and your app at least every 15 minutes, even if no location changes have occurred, and it runs continuously until you stop it.

edit3:将此代码添加到 AppDelegate didFinishLaunchingWithOptions: 以查看应用程序是否被唤醒。它没有被唤醒——我在 TableView 中看不到 200 200 条目。发生了一些可疑的事情。

 if let options = launchOptions {
print("options")
if (launchOptions![UIApplicationLaunchOptionsLocationKey] != nil){
locationManager.startUpdatingLocation()
self.lat.append(Double(200))
self.lon.append(Double(200))
self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle))
NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")
}

代码://应用委托(delegate):

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {

var lat:[CLLocationDegrees]!
var lon:[CLLocationDegrees]!
var times:[String]!
var distances: [String]!

var window: UIWindow?
var locationManager: CLLocationManager!


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

locationManager=CLLocationManager()
locationManager.delegate=self
locationManager.requestAlwaysAuthorization()

let isFirstLaunch = NSUserDefaults.standardUserDefaults().objectForKey("lat")
if isFirstLaunch == nil{
lat = [CLLocationDegrees]()
lon = [CLLocationDegrees]()
times = [String]()
NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")
}else{
lat = NSUserDefaults.standardUserDefaults().arrayForKey("lat") as! [CLLocationDegrees]
lon = NSUserDefaults.standardUserDefaults().arrayForKey("lon") as! [CLLocationDegrees]
times = NSUserDefaults.standardUserDefaults().objectForKey("time") as! [String]
// distances = NSUserDefaults.standardUserDefaults().objectForKey("distance") as! [String]

}
return true
}



func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("location updated")

self.lat.append(locations[0].coordinate.latitude)
self.lon.append(locations[0].coordinate.longitude)
self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle))

NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")

print("Location: \(locations[0].coordinate.latitude) \(locations[0].coordinate.longitude)")
}

func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
print("did change AS")
switch status {
case .AuthorizedWhenInUse:
locationManager.startMonitoringSignificantLocationChanges()
case .AuthorizedAlways:
print("to always")
locationManager.startMonitoringSignificantLocationChanges()
if lat.count==0{
self.lat.append((locationManager.location?.coordinate.latitude)!)
self.lon.append((locationManager.location?.coordinate.longitude)!)

self.times.append(NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .NoStyle, timeStyle: .ShortStyle))

NSUserDefaults.standardUserDefaults().setObject(lat, forKey: "lat")
NSUserDefaults.standardUserDefaults().setObject(lon, forKey: "lon")
NSUserDefaults.standardUserDefaults().setObject(times, forKey: "time")


}

// locationManager.startUpdatingLocation()
break
default:
locationManager.stopMonitoringSignificantLocationChanges()
break
}
}
}

// View Controller

import UIKit

class TableViewController: UITableViewController {

let appDel = UIApplication.sharedApplication().delegate as! AppDelegate

override func viewDidLoad() {
super.viewDidLoad()

NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: "updateTableView", userInfo: nil, repeats: true)
}



override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return appDel.lon.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ID", forIndexPath: indexPath)
cell.textLabel?.text = "\(appDel.lat[indexPath.row]) \(appDel.lon[indexPath.row]) \(appDel.times[indexPath.row])"
cell.textLabel?.font = UIFont.systemFontOfSize(9)


return cell
}

func updateTableView(){
self.tableView.reloadData()
}
}

最佳答案

代码有几个问题:

  1. 位置更新不会在 iOS 启动应用时启动。
  2. 不请求后台位置更新。
  3. 代码依赖于授权状态的变化来启动位置更新
  4. didChangeAuthorizationStatus 方法中缺少 break 语句。

相关文件如下:

第一个文档说,当 iOS 启动应用程序时,必须完全配置位置管理器对象,以便可以将位置事件传递到应用程序。

Upon relaunch, you must still configure a location manager object and call this method [startMonitoringSignificantLocationChanges] to continue receiving location events.

这就是我通常这样做的方式,以确保位置管理器完全启动,无论它是从图标启动还是由 iOS(抱歉,我使用 ObjectiveC)启动。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

NSLog(@"app launching");
bgTask = UIBackgroundTaskInvalid;

locationMgr = [[CLLocationManager alloc] init];
[locationMgr setDelegate:self];
if([locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
[locationMgr setAllowsBackgroundLocationUpdates:YES];
CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus];

if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) {
NSLog(@"relaunching because of significant location change - restarting SLC");
[locationMgr startMonitoringSignificantLocationChanges];
}
else
{
if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) {
NSLog(@"launching with authorization to always use location - starting SLC");
[locationMgr startMonitoringSignificantLocationChanges];
}
else
{
NSLog(@"launching with no authorization to always use location - requesting authorization");
if([locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)])
[locationMgr requestAlwaysAuthorization];
}
}

return YES;
}

注意对 setAllowsBackgroundLocationUpdates 的调用。这是 iOS9 中的新功能,如果您想在后台接收位置更新,则必须在每次应用程序启动时完成。 (这就像“我不是在开玩笑,我知道我在后台模式下要求它们,但我真的想要它们”)。

Apps that want to receive location updates when suspended must include the UIBackgroundModes key (with the location value) in their app’s Info.plist file and set the value of this property to YES.

最后,您不能依赖被调用的 didChangeAuthorizationStatus。如果您拥有授权 kCLAuthorizationStatusAuthorizedAlways,那么调用 [locationMgr requestAlwaysAuthorization] 不会导致授权状态发生变化,因此不会调用 didChangeAuthorizationStatus .

If the authorization status is already known when you call the requestWhenInUseAuthorization or requestAlwaysAuthorization method, the location manager does not report the current authorization status to this method.

关于ios - 重大位置变化不会在设备上触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35467603/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com