我有一个应用程序,它应该在背景中获取对象并使用它们的位置数据为它们生成一个地图快照。当然,我试过MKMapSnapshotter。
结果(经过数周对黑色地图快照的困惑),这个工具似乎只在从主线程调用时才起作用,如下所示:
dispatch_async(dispatch_get_main_queue(), ^{
MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapshotter startWithQueue:dispatch_get_main_queue() completionHandler:^(MKMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
//Use image here. Image would be completely black if not for the first line of code specifying main thread.
}];
});这是框架错误吗?
问题:只有当我的应用程序在前台时才能运行。
发布于 2016-11-10 22:03:41
对于我正在开发的应用程序来说,这有点复杂,因为有许多调用需要下载一组用于多缩放级别的地图块,所以下面的代码可能比您需要的要复杂一些(但显示队列适用于快照)。例如,我需要一个dispatchSemaphore来避免将数百到数千个并发快照排队--这就限制了它们在线程上捕获大约25个并发快照。
另外,我是在Swift 3中这样做的,所以在GCD中可能会有一些变化,让我在为您介绍问题时做到这一点。
这里的逻辑是在主队列保持畅通的情况下,在processQueue中启动所有请求,从而使UI保持活动状态。然后,当多达25个请求在任何时候通过信号量门时,它们都会通过snapshotQueue调用进入snapshotter.start。当一个快照完成时,将启动另一个快照,直到processQueue为空。
unowned let myself = self // Avoid captures in closure
let processQueue = DispatchQueue(label: "processQueue", qos: .userInitiated)
let snapshotQueue = DispatchQueue(label: "snapshotQueue")
var getSnapshotter = DispatchSemaphore(value: 25)
processQueue.async
{
var centerpoint = CLLocationCoordinate2D()
centerpoint.latitude = (topRight.latitude + bottomLeft.latitude) / 2.0
centerpoint.longitude = (topRight.longitude + bottomLeft.longitude) / 2.0
let latitudeDelta = abs(topRight.latitude - bottomLeft.latitude)
let longitudeDelta = abs(topRight.longitude - bottomLeft.longitude)
let mapSpan = MKCoordinateSpanMake(latitudeDelta, longitudeDelta)
var mapRegion = MKCoordinateRegion()
mapRegion.center = centerpoint
mapRegion.span = mapSpan
let options = MKMapSnapshotOptions()
options.region = mapRegion
options.mapType = .standard
options.scale = 1.0
options.size = CGSize(width: 256, height: 256)
myself.getSnapshotter.wait() // Limit the number of concurrent snapshotters since we could invoke very many
let snapshotter = MKMapSnapshotter(options: options)
snapshotter.start(with: myself.snapshotQueue, completionHandler: {snapshot, error in
if error == nil
{
self.saveTile(path: path, tile: snapshot!.image, z: z, x: x, y: y)
// saveTile writes the image out to a file in the mapOverlay file scheme
} else {
print("Error Creating Map Tile: ", error!)
}
if myself.getSnapshotter.signal() == 0
{
// show status as completed (though could be up to 20 snapshots finishing, won't take long at this point
}
})
}这对我的工作,获得高达5K快照,以建立一个7缩放水平离线地图图像集,而不阻塞用户界面,所以我是相当舒适的代码。
https://stackoverflow.com/questions/40475345
复制相似问题