Остановить повторную загрузку офлайн-карты MapBox

Я использую 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
            }
        }

person M.Strachan    schedule 19.01.2018    source источник
comment
Привет, Вы получили решение. пожалуйста, помогите мне, я тоже застрял здесь.   -  person Niraj Paul    schedule 09.08.2018


Ответы (2)


См. mapbox Doc, MGLOfflinePackStateUnknown = 0 означает, что плитки уже загружены, поэтому мы можем аналогичным образом проверить состояние автономного пакета:

Код находится в Objective c, вы можете преобразовать его в быстрый

-(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;
            }
        }
}
person Niraj Paul    schedule 09.08.2018

Вы должны использовать MGLOfflineStorage.shared().packs, обратите внимание, что используйте этот метод только после полной загрузки карты. Реализуйте метод MGLMapViewDelegate:

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

Этот фрагмент кода распечатает все ваши пакеты, которые в настоящее время хранятся на устройстве. Не делайте этого в viewDidLoad или viewWillAppear методах, MGLOfflineStorage.shared().packs вернет ноль.

После того, как вы получите свои пакеты, вы можете просмотреть их и выбрать тот пакет, который вам нужен, чтобы возобновить загрузку или удаление его из автономного хранилища.

ОБНОВЛЕНИЕ

Сохраните где-нибудь в коде название вашего пакета содержимого для региона загрузки и переменную 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)
    }
}
person Andrew Son    schedule 16.04.2018
comment
Будет полезно, если вы объясните больше - person Niraj Paul; 09.08.2018
comment
@NirajPaul обновляет ответ с функцией, которая проверяет, загружена ли карта - person Andrew Son; 10.08.2018