停止离线MapBox地图重新下载

时间:2018-01-19 10:35:26

标签: ios swift mapbox offline

我正在使用MapBox下载离线地图。这样我的用户在旅行时就可以访问特定区域。 使用MapBox Offline文档时,似乎只要有连接,MapBox Map就会尝试下载(重新下载)。

如何设置我的MapBox以便在存储中执行检查以查看地图是否已下载?

func startOfflinePackDownload() {

    let region = MGLTilePyramidOfflineRegion(styleURL: mapView.styleURL, bounds: mapView.visibleCoordinateBounds, fromZoomLevel: mapView.zoomLevel, toZoomLevel: 13)

    let userInfo = ["name": "My Offline Pack"]
    let context = NSKeyedArchiver.archivedData(withRootObject: userInfo)

    MGLOfflineStorage.shared().addPack(for: region, withContext: context) { (pack, error) in
        guard error == nil else {
            // The pack couldn’t be created for some reason.
            print("Error: \(error?.localizedDescription ?? "unknown error")")
            return
        }
        // Start downloading.
        pack!.resume()
    }
}

我找到了以下代码来检查下载是否已经存在......所以这将在我的“startOfflinePackDownload()'以上功能。 但是,较新版本的MapBox无法识别代码。有人能帮我这个吗?

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"] == "My Offline Pack" {
                // allready downloaded
                return
            }
        }

2 个答案:

答案 0 :(得分:1)

您应该使用MGLOfflineStorage.shared().packs,请注意,只有在地图完全加载后才能使用此方法。实现MGLMapViewDelegate方法:

func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
    print(MGLOfflineStorage.shared().packs)
}

此代码段将打印当前存储在设备上的所有包。不要在viewDidLoadviewWillAppear方法中执行此操作,MGLOfflineStorage.shared().packs将返回nil。

收到后,您可以对其进行迭代并选择该包,以便从离线存储中继续下载或删除它

<强>更新

在代码中的某处保存下载区域的内容包名称和Bool变量以确定您的包是否已下载

    let packageName = "YourPackageName"
    var isPackageNameAlreadyDownloaded = false

下面的Func检查是否已下载packageName

 func downloadPackage() {    
     if let packs = MGLOfflineStorage.shared().packs {
        if packs.count > 0 {

            // Filter all packs that only have name
            let filteredPacks = packs.filter({
                guard let context = NSKeyedUnarchiver.unarchiveObject(with: $0.context) as? [String:String] else {
                    print("Error retrieving offline pack context")
                    return false
                }
                let packTitle = context["name"]!
                return packTitle.contains("(Data)") ? false : true
            })


            // Check if filtered packs contains your downloaded region
            for pack in filteredPacks {
                var packInfo = [String:String]()
                guard let context = NSKeyedUnarchiver.unarchiveObject(with: pack.context) as? [String:String] else {
                    print("Error retrieving offline pack context")
                    return
                }
                // Recieving packageName
                let packTitle = context["name"]!
                if packTitle == packageName {

                    // Simply prints how download progress
                    print("Expected: \(pack.progress.countOfResourcesExpected); Completed: \(pack.progress.countOfBytesCompleted)")
                    print("Tile bytes completed: \(pack.progress.countOfTileBytesCompleted); Tiles Completed: \(pack.progress.countOfTilesCompleted)")

                    // If package isn't fully downloaded resume progress. If it downloaded - it'll check and won't redownload it
                    pack.resume()
                    isPackageNameAlreadyDownloaded = true
                    break
                } else {
                    // This is another region
                }
            }

        }

    }
    // If region is downloaded - return
    if isPackageNameAlreadyDownloaded {
        return
    }

    // if not - create region, map style url (which you recieve from MapBox Styler


    let region = MGLTilePyramidOfflineRegion(styleURL: URL(string: YourMapStyleUrl)!, bounds: YourBoundaries, fromZoomLevel: 12, toZoomLevel: 16.5)

    // Save packageName in Library and archive in package context.
    let userInfo = ["name": packageName]
    let context = NSKeyedArchiver.archivedData(withRootObject: userInfo)

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

        // Start downloading.
        pack!.resume()
        print(MGLOfflineStorage.shared().packs)
        // Shows the download progress in logs
        print(pack!.progress)
    }
}

答案 1 :(得分:0)

请参阅mapbox Doc,MGLOfflinePackStateUnknown = 0表示磁贴已经下载,因此我们可以同样地检查Offline pack的状态:

  

代码在Objective c中,您可以转换为swift

-(void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {

        NSArray *arrTiles = MGLOfflineStorage.sharedOfflineStorage.packs;


        if (arrTiles.count==0) {
            [self startOfflinePackDownload];
        }

        for (MGLOfflinePack *downloadPack in arrTiles) {
            NSLog(@"title: %@",downloadPack.region.description );

            switch (downloadPack.state) {
                case MGLOfflinePackStateUnknown:
                     [downloadPack requestProgress];
                    break;

                case MGLOfflinePackStateComplete:

                    break;

                case MGLOfflinePackStateInactive:
                    [downloadPack resume];
                    break;

                case MGLOfflinePackStateActive:
                   [self startOfflinePackDownload];
                    break;

                case MGLOfflinePackStateInvalid:
                  //  NSAssert(NO, @"Invalid offline pack at index path %@", indexPath);
                    break;
            }
        }
}