Thx. It works now. Had a problem with returning values. But took care of it.
and BTW, your tutorial is awesome. Learned so much from this.
Thx again.
Audrey:
Thanks for clear and useful tutorial. I would like to adapt it to an app showing World War I monuments in New Jersey but am unsure as to how to format the data and images (Iām new at this.) Any suggestions?
do you mean, the data isnāt already in a database, like my Honolulu Art?
if you store the data in the app itself, you donāt need to work with JSON; use the file manager or a property list: Saving Data video course
do you want to make an iOS app version of this page?
it seems they only provide addresses, so youād need to use geocoding to get the latitude and longitude: MapKit video course part 4
for images, you could link to theirs, but if they move them, youāll need to update your app; also, you probably need their permission before you make your app publicly available.
is it an option to contact them directly, and ask for their data?
Hi, thanks a lot for the tutorial , is very clary and easy.
I want to ask a question .
I need to open the same JSON file from WEB URL , for example :āHTTP://localhost/xxxx.JSONā , not in build path.
How I can do ?
Thank you very much for your answer.
If the delegate works like a table view delegate, why should you split up the creation of an MKPinAnnotationView.
This works too:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let artwork = annotation as? Artwork {
var artworkView = mapView.dequeueReusableAnnotationViewWithIdentifier("ArtworkView")
artworkView.annotation = artwork
artworkView.canShowCallout = true
return artworkView
}
return nil
}
Ok, never mind.
If I donāt create the MKAnnotationView first and just dequeue it all the time, I wonāt get the callout button.
hi Paolo: if your file is really local, you can use Data(contentsOf:)
; but if the file is on a remote server, you should use URLSession. You can start with NSURLSession Tutorial - Iāve written an update for this, which should appear next month or so. Or look at our URLSession video course.
Data(contentsOf:)
blocks the main thread, so you shouldnāt use it to get data from remote servers.
hi Sam: thanks for posting! Iām glad you figured it out
i have try but is not simple, can you help me ?
var networks = Artwork
func loadInitialData() {
// 1
var url: URL!
url = URL(string: "https://10.6.68.141/node.json")
// let fileName = Bundle.main.path(forResource: ānodeā, ofType: ājsonā);
do {
data = try URL(contentsOf: url)
// data = try Data(contentsOf: URL(fileURLWithPath: fileName!), options: NSData.ReadingOptions(rawValue: 0))
} catch _ {
data = nil
}
// 2
var jsonObject: Any? = nil
if let data = data {
do {
jsonObject = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions(rawValue: 0))
} catch _ {
jsonObject = nil
}
}
Hi, delete last post , I found the solution and it work.
Thank very much for your support.
Hi , sorry but in local work but I donāt find a solution with URLSession for remote JSON link .
Here the code that working with local link . Can you help me ? very thanks
var networks = Artwork
func loadInitialData() {
// 1
var url: URL!
url = URL(string: "http://10.6.82.163/node.json")
var data: Data!
do {
data = try? Data(contentsOf: url)
} catch _ {
print("Error: (data: contentsOf: url)")
data = nil
}
// 2
var jsonObject: Any? = nil
if let data = data {
do {
jsonObject = try JSONSerialization.jsonObject(with: data)
} catch _ {
jsonObject = nil
}
// 3
if let jsonObject = jsonObject as? [String: Any],
// 4
let jsonData = JSONValue.fromObject(jsonObject)?["data"]?.array {
for artworkJSON in jsonData {
if let artworkJSON = artworkJSON.array,
// 5
let artwork = Artwork.fromJSON(artworkJSON) {
self.networks.append(artwork)
}
}
}
}
}
}
Look at the sample project of NSURLSession Tutorial: func searchBarSearchButtonClicked
and the func updateSearchResults
that it calls.
You might also need to look at our JSON tutorial, because your JSON data will probably be different from PublicArt.json
Hi @audrey Where can I find the Xcode 8 version of this project? I donāt want to use Xcode 9 yet and am trying to follow the tutorial but am stuck at MKMarkerAnnotationView since that is not in Xcode 8.
Please advise. Thank you!
Hi Ernie: hereās a copy of the tutorial and projects from before this last update to Xcode 9 beta:
MapKitTutorial_Xcode8.zip (1.6 MB)
Hi Audrey - would you have any examples where MKMapviewdelegate methods are held in a separate swift file / class, so that map views in different view controllers can call the same methods? Or is this a stupid idea? best regards AC.
hi AC: the delegate methods are usually implemented in an extension of the view controller. I suppose you could create a delegate class ā a singleton? ā that all the view controllers access.
but I take it, it is not common to do so? The background to my question is this, If you have one app, multiple viewcontrollers with a mapview on each (for different purposes) I would need one ādraw the map pinā-method for each mapview, right? Lazy as I am, I thought (with my limited experience) I could consolidate this into using one such method for all map views. But I have abandoned it for now Thanks for your tutorial, I consult it many times. /AC
actually, it could work, to create a mapViewService class ā¦ setting up the map view doesnāt often interact with the host view controllerās outlets? making the view controller the mapViewās delegate is more convenient if the delegate methods have to get/set values of view controller properties. Otherwise, a separate class could work well, and reduce code duplication.
Hello! Can you help me please. I add phone number in subtitles in annotation. How I can make when user tap on phone number starting call. Or when user tap on URL link safari open.
sorry Nikita, this is beyond my expertise.
see if this helps:
you can create a UITextView for view.detailCalloutAccessoryView
instead of a UILabel, then try Paul Hudsonās example.
the url for a phone number is ātel://ā + the number, and you call UIApplication.shared.open