Ios 设备上不会触发重大位置更改
我正在使用重要的位置变化监控。当我在模拟器中运行代码并选中高速公路选项时,我会定期更新位置。我抓取这些更新并将它们保存在NSUserDefaults中,然后每隔10秒更新一次tableview,以便查看是否有任何更新。如果我在真实设备上运行该应用程序,则不会得到任何更新。我把手机放在口袋里,走了80多公里,去过两个城市。零更新。不确定我是否把事情搞砸了。我正在附上密码。代码是复制粘贴的,可以随意测试。只需确保在故事板中使用TableViewController并将单元格id设置为id。我缺少什么?我正在测试iphone5 info.plist: 编辑:在apple docs中找到。是否应以不同方式创建我的Ios 设备上不会触发重大位置更改,ios,core-location,cllocationmanager,Ios,Core Location,Cllocationmanager,我正在使用重要的位置变化监控。当我在模拟器中运行代码并选中高速公路选项时,我会定期更新位置。我抓取这些更新并将它们保存在NSUserDefaults中,然后每隔10秒更新一次tableview,以便查看是否有任何更新。如果我在真实设备上运行该应用程序,则不会得到任何更新。我把手机放在口袋里,走了80多公里,去过两个城市。零更新。不确定我是否把事情搞砸了。我正在附上密码。代码是复制粘贴的,可以随意测试。只需确保在故事板中使用TableViewController并将单元格id设置为id。我缺少什么
locationManager
由于位置更新而重新启动应用程序时,启动
选项字典已传递给您的
应用程序:将使用选项完成启动:或
application:didFinishLaunchingWithOptions:方法包含
UIApplicationLaunchActionSlocationKey键。钥匙的存在
表示新位置数据正在等待发送到应用程序。
要获取该数据,必须创建新的CLLocationManager对象
并重新启动在启动之前运行的位置服务
应用程序的终止。当您重新启动这些服务时,位置
manager将所有挂起的位置更新传递给其代理
编辑2:
基于此,位置应至少每15分钟更新一次。我的代码中的错误得到了确认
如果GPS水平精度对您的应用程序不重要,并且您不需要
连续跟踪,您可以使用重大更改位置
服务重要的是你要使用重要的变更位置
服务正确,因为它至少会唤醒系统和应用程序
每15分钟一次,即使没有发生位置变化
持续运行,直到您停止
edit3:将此代码添加到AppDelegatedidFinishLaunchingWithOptions:
,以查看应用程序是否被唤醒。它没有被唤醒——我在表视图中没有看到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")
}
代码:
//AppDelegate:
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
}
}
}
//视图控制器
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()
}
}
我想不管你在哪里,你都得开始约会?您是否尝试过插入断点以查看到达的位置?代码有几个问题:
你真的看到授权申请了吗?如果没有,您的plist中是否有NSLocationAlwaysUsageDescription?是,请求会弹出。是的,在info.plist中设置了NSLocationAlwaysUsageDescription字符串。您是否通过双击home按钮并向上滑动应用程序来终止应用程序?如果你以这种方式杀死一个应用程序,它将不会运行后台重要的更改服务。是的,我正在这样做。我认为大多数用户也经常这样做。是否有更好的方法来挂起应用程序?不,这不会挂起应用程序,会完全终止应用程序并阻止进一步的后台交互。不要关闭应用程序,只需点击home按钮一次,然后转到另一个应用程序,而不关闭另一个应用程序。如果我将startUpdatingLocation设置为true,则每秒会更新3次。我认为这只是标准的定位服务。我没有,因为它在模拟器上工作得很好。是否可以在后台的挂起应用程序上使用断点?@krompir2-不,在这种情况下不能使用断点。我通常
NSLog
消息(因此我可以观看控制台)。我还发现,将消息记录到一些持久性存储中,然后当我将应用程序置于前台时,将这些保存的消息显示在表视图或类似的视图中,这是很有用的,因此,我可以诊断应用程序不在前台时发生的情况。您可以在挂起或甚至未运行的进程上设置断点。如果进程挂起,请在Xcode中单击调试菜单并选择“附加到进程”-选择您的进程。您现在已连接,并且当进程
- (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;
}