MGLOfflinePackDelegate

MGLOfflinePackDelegate

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

我的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]
    }
}

这几乎全部取自文档,因此为什么从未调用委托函数(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/

10-09 10:12