Reputation: 2896
I am fairly new to iOS programming and am building my app in Swift for iOS8 and also implementing the Mapbox-ios-sdk as I want my user to be able to download offline map areas.
I've been able to download offline map areas in the cache, however it seems the cache is not accessed when I turn of Wifi and cellular data. The Map Tiles are not coming up. Only the Map Tiles that were automatically cached are showing.
I see that the tiles are being downloaded (RMTileCache.db is growing, the RMTileCacheBackgroundDelegate methods didBeginBackgroundCacheWithCount, didBackgroundCacheTile and tileCacheDidFinishBackgroundCache are being called) and, when looking directly in the db file I also see that the correct tiles have been downloaded.
But, when I then turn off Wifi and Cellular data, the map tiles are not loaded on the screen. I've tried several options with adding additional RMDatabase Caches etc, but nothing seems to work. I'm hoping that someone out there ran into the same problem and can help me out.
My code is roughly based on this piece here: http://mapbox.com/mapbox-ios-sdk/#tile_caching__class
Class Level relevant variables:
var tileSource: RMMapboxSource = RMMapboxSource()
@IBOutlet var mapView: RMMapView!
viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let fullPath: String = NSBundle.mainBundle().pathForResource("mapbox", ofType: "json")!
var errorInFullPath:NSErrorPointer? = NSErrorPointer()
let tileJSON: String? = String(contentsOfFile: fullPath, encoding:NSUTF8StringEncoding, error: errorInFullPath!)
tileSource = RMMapboxSource(tileJSON: tileJSON)
initializeMap()
}
The Map initialization:
func initializeMap() {
mapView = RMMapView(frame: self.view.bounds)
mapView.tileSource = tileSource
tileSource.cacheable = true
mapView.adjustTilesForRetinaDisplay = true
mapView.userInteractionEnabled = true
mapView.zoom = 9
self.view.addSubview(mapView)
mapView.delegate = self
}
The download operation:
func startDownload() {
mapView.tileCache.backgroundCacheDelegate = self
mapView.tileCache.beginBackgroundCacheForTileSource(tileSource, southWest: sw, northEast: ne, minZoom: 1, maxZoom: zoomLevel)
}
sw, ne and zoomLevel have been defined elsewhere in the code and their values are good when I print them out just before the beginBackgroundCacheForTileSource command.
I'm not sure what I'm doing wrong here. Probably something really stupid, but I've been trying to find it for 2 days now. Hope someone can help me out.
Thanks in advance!
Upvotes: 1
Views: 2080
Reputation: 2896
OK, so I got it working thanks to the tip of incanus. Turns out it was two problems which made it more difficult to analyze and find the root cause.
1st problem was indeed that I had some layout things going on in viewDidLoad which somehow prevented cashed map tiles to be loaded.
2nd problem was that the area I was downloading was slightly different from the area I thought I was downloading. So I just need to tweak the pixelToCoordinate method of RMMapView which I'm using to get this right.
For those of you interested. I created a separate clean swift file without any layout in it, just to follow up on Incanus' comment. This worked for me!
Thanks to Incanus. Hope someone else will find this useful too.
import UIKit
class ViewOfflineMapAreaViewController: UIViewController, RMMapViewDelegate {
var tileSource: RMMapboxSource = RMMapboxSource()
@IBOutlet var mapView: RMMapView!
override func viewDidLoad() {
super.viewDidLoad()
let fullPath: String = NSBundle.mainBundle().pathForResource("mapbox", ofType: "json")!
var errorInFullPath:NSErrorPointer? = NSErrorPointer()
let tileJSON: String? = String(contentsOfFile: fullPath, encoding:NSUTF8StringEncoding, error: errorInFullPath!)
tileSource = RMMapboxSource(tileJSON: tileJSON)
tileSource.retryCount = 3
initializeMap()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func initializeMap() {
mapView = RMMapView(frame: self.view.bounds)
mapView.tileSource = tileSource
tileSource.cacheable = true
mapView.adjustTilesForRetinaDisplay = true
mapView.userInteractionEnabled = true
mapView.zoom = 9
mapView.delegate = self
//These two lines are just to resize the mapView upon device rotation
mapView.setTranslatesAutoresizingMaskIntoConstraints(true)
mapView.autoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth
}
override func viewDidAppear(animated: Bool) {
self.view.addSubview(mapView)
}
}
Upvotes: 4
Reputation: 5128
You are saving the TileJSON locally and using it for instantiation, which is needed when you are operating offline. But I think your problem may be in doing layout during -viewDidLoad
. Try this in -viewWillAppear:
or later and I think you'll see different results.
Upvotes: 0