gpt4 book ai didi

ios - 我如何正确使用 mapbox 的新 MGLOfflinePackDelegate?

转载 作者:搜寻专家 更新时间:2023-11-01 06:40:29 24 4
gpt4 key购买 nike

我正在创建一个需要离线 map 的应用程序。我正在使用 MapBox 进行测试,它从今天开始就支持离线 map (耶!)。我现在拥有的代码似乎可以用于下载 map ,但是报告进度的委托(delegate)永远不会触发,而且我不知道为什么会这样。

我的 mapView 有这个类:

import UIKit
import Mapbox

class MapController: UIViewController, MGLMapViewDelegate, UIPopoverPresentationControllerDelegate {

@IBOutlet var mapView: MGLMapView!

override func viewDidLoad() {
super.viewDidLoad()
downloadIfNeeded()
mapView.maximumZoomLevel = 18
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

func downloadIfNeeded() {
MGLOfflineStorage.sharedOfflineStorage().getPacksWithCompletionHandler { (packs, error) in guard error == nil else {
return
}
for pack in packs {
let userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context) as! [String: String]
if userInfo["name"] == "London" {
// allready downloaded
return
}
}

// define the download region
let sw = CLLocationCoordinate2DMake(51.212120, 4.415906)
let ne = CLLocationCoordinate2DMake(51.223781, 4.442401)

let bounds = MGLCoordinateBounds(sw: sw, ne: ne)
let region = MGLTilePyramidOfflineRegion(styleURL: MGLStyle.streetsStyleURL(), bounds: bounds, fromZoomLevel: 10, toZoomLevel: 12)

let userInfo = ["name": "London"]
let context = NSKeyedArchiver.archivedDataWithRootObject(userInfo)

MGLOfflineStorage.sharedOfflineStorage().addPackForRegion(region, withContext: context) { (pack, error) in
guard error == nil else {
return
}

// create popup window with delegate
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let downloadProgress: MapDownloadController = storyboard.instantiateViewControllerWithIdentifier("MapDownloadController") as! MapDownloadController
downloadProgress.modalPresentationStyle = .Popover
downloadProgress.preferredContentSize = CGSizeMake(300, 150)

let popoverMapDownloadController = downloadProgress.popoverPresentationController
popoverMapDownloadController?.permittedArrowDirections = .Any
popoverMapDownloadController?.delegate = self
popoverMapDownloadController?.sourceView = self.mapView
popoverMapDownloadController?.sourceRect = CGRect(x: self.mapView.frame.midX, y: self.mapView.frame.midY, width: 1, height: 1)
self.presentViewController(downloadProgress, animated: true, completion: nil)

// set popup as delegate <----
pack!.delegate = downloadProgress

// start downloading
pack!.resume()
}
}
}
}

MapDownloadController 是一个显示为弹出窗口的 View (参见上面的代码)并具有 MGLOfflinePackDelegate:

import UIKit
import Mapbox

class MapDownloadController: UIViewController, MGLOfflinePackDelegate {

@IBOutlet var progress: UIProgressView!
@IBOutlet var progressText: UILabel!

override func viewDidLoad() {
super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

func offlinePack(pack: MGLOfflinePack, progressDidChange progress: MGLOfflinePackProgress) {
// this function is never called, but why? <----
let completed = progress.countOfResourcesCompleted
let expected = progress.countOfResourcesExpected
let bytes = progress.countOfBytesCompleted

let MB = bytes / 1024

let str: String = "\(completed)/\(expected) voltooid (\(MB)MB)"
progressText.text = str

self.progress.setProgress(Float(completed) / Float(expected), animated: true)
}

func offlinePack(pack: MGLOfflinePack, didReceiveError error: NSError) {
// neither is this one... <----
let userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context) as! [String: String]
let strError = error.localizedFailureReason
}

func offlinePack(pack: MGLOfflinePack, didReceiveMaximumAllowedMapboxTiles maximumCount: UInt64) {
// .. or this one <----
let userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context) as! [String: String]
}
}

这几乎都是从文档中获取的,那么为什么委托(delegate)的函数 (func offlinePack) 从未被调用过?我确实使用断点进行了测试,所以我确定不是。尽管如此,仍会显示弹出窗口并下载该区域。 (通过观察网络流量和列出离线包的其他代码进行检查。)

最佳答案

这是 Minh’s answer 的一个极其简单的实现, 使用 current v3.2.0b1 example code .由于我们仍在开发 v3.2.0 版本,因此预计此答案会很快过时。

import UIKit
import Mapbox

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate, MGLOfflinePackDelegate {

@IBOutlet var mapView: MGLMapView!

// Array of offline packs for the delegate work around (and your UI, potentially)
var offlinePacks = [MGLOfflinePack]()

override func viewDidLoad() {
super.viewDidLoad()

mapView.maximumZoomLevel = 2
downloadOffline()
}

func downloadOffline() {
// Create a region that includes the current viewport and any tiles needed to view it when zoomed further in.
let region = MGLTilePyramidOfflineRegion(styleURL: mapView.styleURL, bounds: mapView.visibleCoordinateBounds, fromZoomLevel: mapView.zoomLevel, toZoomLevel: mapView.maximumZoomLevel)

// Store some data for identification purposes alongside the downloaded resources.
let userInfo = ["name": "My Offline Pack"]
let context = NSKeyedArchiver.archivedDataWithRootObject(userInfo)

// Create and register an offline pack with the shared offline storage object.
MGLOfflineStorage.sharedOfflineStorage().addPackForRegion(region, withContext: context) { (pack, error) in
guard error == nil else {
print("The pack couldn’t be created for some reason.")
return
}

// Set the pack’s delegate (assuming self conforms to the MGLOfflinePackDelegate protocol).
pack!.delegate = self

// Start downloading.
pack!.resume()

// Retain reference to pack to work around it being lost and not sending delegate messages
self.offlinePacks.append(pack!)
}
}

func offlinePack(pack: MGLOfflinePack, progressDidChange progress: MGLOfflinePackProgress) {
let userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context) as! [String: String]
let completed = progress.countOfResourcesCompleted
let expected = progress.countOfResourcesExpected
print("Offline pack “\(userInfo["name"])” has downloaded \(completed) of \(expected) resources.")
}

func offlinePack(pack: MGLOfflinePack, didReceiveError error: NSError) {
let userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context) as! [String: String]
print("Offline pack “\(userInfo["name"])” received error: \(error.localizedFailureReason)")
}

func offlinePack(pack: MGLOfflinePack, didReceiveMaximumAllowedMapboxTiles maximumCount: UInt64) {
let userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context) as! [String: String]
print("Offline pack “\(userInfo["name"])” reached limit of \(maximumCount) tiles.")
}

}

关于ios - 我如何正确使用 mapbox 的新 MGLOfflinePackDelegate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36043359/

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