{"id":75259,"date":"2026-10-27T03:01:00","date_gmt":"2026-10-26T17:01:00","guid":{"rendered":"https:\/\/www.rjmprogramming.com.au\/ITblog\/?p=75259"},"modified":"2026-10-26T17:39:40","modified_gmt":"2026-10-26T07:39:40","slug":"swift-playgrounds-on-macos-map-revisit-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/swift-playgrounds-on-macos-map-revisit-tutorial\/","title":{"rendered":"Swift Playgrounds on macOS Map Revisit Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_map_revisit.gif\" rel=\"noopener\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Swift Playgrounds on macOS Map Revisit Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_map_revisit.gif\" title=\"Swift Playgrounds on macOS Map Revisit Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Swift Playgrounds on macOS Map Revisit Tutorial<\/p><\/div>\n<p>With a newer version of macOS <a target=\"_blank\" title='Xcode IDE information from Apple' href='https:\/\/developer.apple.com\/technologies\/tools\/' rel=\"noopener\">Xcode<\/a> Version 26.6 (17F113), we&#8217;re revisiting the &#8230;<\/p>\n<p><code><br \/>\nNew -&gt; Playground... -&gt; Map<br \/>\n<\/code><\/p>\n<p> &#8230; concepts developed upon with <a title='Swift Playgrounds on macOS Map Emoji Tutorial' href='#sposmet'>Swift Playgrounds on macOS Map Emoji Tutorial<\/a>.<\/p>\n<p>This time around the motivation is different, and that &#8220;basis in source workflow&#8221; will be &#8230;<\/p>\n<ul>\n<li>developed <font size=1>(or integrated)<\/font> onto from without &#8230;<\/li>\n<li>and developed from within, as well, and that available to be developed onto as well<\/li>\n<\/ul>\n<p>But for today, we took that &#8220;basis in source workflow&#8221; playground above and tweaked it&#8217;s &#8230;<\/p>\n<ol>\n<li>latitude and longitude geographicals basis<\/li>\n<li>map distance<\/li>\n<li>map pin label<\/li>\n<\/ol>\n<p> &#8230; to be able to show, hereabouts &#8230;<\/p>\n<blockquote><p>\n<a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_map_revisit.gif\" rel=\"noopener\">Luna&#8217;s Den<\/a>\n<\/p><\/blockquote>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=\"_blank\" href='\/\/www.rjmprogramming.com.au\/ITblog\/new-swift-playgrounds-on-macos-map-emoji-tutorial\/' rel=\"noopener\">New Swift Playgrounds on macOS Map Emoji Tutorial<\/a> ...<\/p>\n\n\n\n\n\n<hr>\n\n\n\n\n\n<p id='sposmet'>Previous relevant <a target=\"_blank\" title='Swift Playgrounds on macOS Map Emoji Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/swift-playgrounds-on-macos-map-emoji-tutorial\/' rel=\"noopener\">Swift Playgrounds on macOS Map Emoji Tutorial<\/a> is shown below.<\/p>\n\n\n\n[caption id=\"\" align=\"alignnone\" width=\"220\" caption=\"Swift Playgrounds on macOS Map Emoji Tutorial\"]<a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_map_portsmore.jpg\" rel=\"noopener\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Swift Playgrounds on macOS Map Emoji Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_map_portsmore.jpg\" title=\"Swift Playgrounds on macOS Map Emoji Tutorial\"  style=\"float:left;\" \/><\/a>[\/caption]\n\n\n\n<p>We find work in the <a target=\"_blank\" title='Google Maps' href='http:\/\/maps.google.com' rel=\"noopener\">Google Maps<\/a> or <a target=\"_blank\" title='Apple Maps' href='https:\/\/developer.apple.com\/maps\/' rel=\"noopener\">Apple Maps<\/a> <font size=1>style of<\/font> related \"where<font size=1> of life<\/font>\" development work has you reaching for more and more layers of functionality, but we want to draw a line in the sand at ...<\/p>\n\n\n\n\n\n<ul>\n\n\n<li>using emojis even before any pin clicking, rather than ...<\/li>\n\n\n\n\n<li>any NSImage or UIImage image interventions further down the \"clicking\" track ...<\/li>\n\n\n\n\n<li>at least, in terms of using Xcode Swift macOS platform Playgrounds (though it could well be easier with iOS platforms because we could \"import UIKit\" in that scenario)\n<\/ul>\n\n\n\n\n\n<p> ... even though the great <a target=\"_blank\" href='https:\/\/www.kodeco.com\/7738344-mapkit-tutorial-getting-started' title='MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com' rel=\"noopener\">MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com<\/a> gave us lots of ideas in this line of thinking and trying.   So, further to yesterday's <a title='Swift Playgrounds on macOS Map GeoJson Tutorial' href='#sposmgjt'>Swift Playgrounds on macOS Map GeoJson Tutorial<\/a>'s progress, today ...<\/p>\n\n\n\n\n\n<ul>\n\n\n<li>we add another \"map.geojson\" Ports (around the world) data source idea into the Playground's Resources folder, we thank <a target=\"_blank\" title='GeoJson data sources, thanks' href='http:\/\/geojson.xyz\/' rel=\"noopener\">geojson.xyz<\/a> for ... and we ...<\/li>\n\n\n\n\n<li>use Geelong \"PublicArt.geojson\" pins adorned with emojis, but find that Swift is not great at any equivalent to Javascript's String.fromCodePoint([decimalHTMLEntityNumber]), meaning we literally copy emojis into the Swift code to achieve this<\/li>\n\n\n<\/ul>\n\n \n\n\n\n<p>Why the Port data?  Well, when you think of it, it's not too far to a port as you zoom out and get context with the map, in <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/MyPlayground.swift--GETME\" title=\"MyPlayground.swift\" rel=\"noopener\">our changed<\/a> <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/MyPlayground.swift--GETME\" title=\"MyPlayground.swift\" rel=\"noopener\">MyPlayground.swift<\/a> Swift source code macOS Swift desktop application code ...<\/p>\n\n\n\n<code>\n\/\/: A MapKit based Playground\n<br \/>\nimport PlaygroundSupport\nimport AppKit\nimport Cocoa\nimport MapKit\n<br \/>\nprivate var artworks: [Artwork] = []\nprivate var ports: [Port] = []\nprivate var rightCalloutAccessoryView: [NSView]\npublic var nsg: [NSString]\n\/\/public var imageURL: [URL?]\n\/\/public var imageData: [Data]\n<br \/>\n\/\/ imageURL = [NSURL URLWithString:@\"file:\/\/\/Applications\/MAMP\/htdocs\/swift_map_more-2.jpg\"]\n\/\/let imageURL =\n\/\/NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first?.URLByAppendingPathComponent(\"swift_map_more-2.jpg\")\n<br \/>\nclass ViewController: NSViewController {\n<br \/>\n    @objc\n    func printSomething() {\n        print(\"Hello\")\n    }\n<br \/>\n    override func viewDidLoad() {\n        super.viewDidLoad()\n<br \/>\n        \/\/ Do any additional setup after loading the view.\n        let myButtonRect = CGRect(x: 10, y: 10, width: 100, height: 10)\n        let myButton =  NSButton(frame: myButtonRect)\n        view.addSubview(myButton)\n<br \/>\n        myButton.target = self\n        myButton.action = #selector(ViewController.printSomething)\n    }\n<br \/>\n    \/\/override var representedObject: AnyObject? {\n    \/\/    didSet {\n        \/\/ Update the view, if already loaded.\n    \/\/    }\n    \/\/ }\n}\n<br \/>\nclass ArtworkView: MKAnnotationView {\n  override var annotation: MKAnnotation? {\n    willSet {\n      guard let artwork = newValue as? Artwork else {\n        return\n      }\n<br \/>\n      canShowCallout = true\n      calloutOffset = CGPoint(x: -5, y: 5)\n      let theButton: NSButton = NSButton()\n          theButton.setButtonType(NSButton.ButtonType.pushOnPushOff)\n<br \/>\n          rightCalloutAccessoryView = theButton\n<br \/>\n      image = artwork.image\n    }\n  }\n}\n<br \/>\nclass ArtworkMarkerView: MKMarkerAnnotationView {\n    override var annotation: MKAnnotation? {\n    willSet {\n      \/\/ 1\n      var i = 22247\n       guard let artwork = newValue as? Artwork else {\n        return\n      }\n      canShowCallout = true\n      calloutOffset = CGPoint(x: -5, y: 5)\n<br \/>\n      \/\/rightCalloutAccessoryView = NSButton(type: .detailDisclosure)\n      let mapsButton: NSButton = NSButton()\n        mapsButton.setButtonType(NSButton.ButtonType.pushOnPushOff)\n        \/\/ Insert code here to initialize your application\n        \/\/self.imageView.image = image;\n        \/\/ initialise your image object with the image data\n        \/\/do {\n        \/\/    let imageData = try Data(contentsOf: imageURL)\n        \/\/    image = NSImage.init(data: imageData)\n        \/\/} catch {\n        \/\/    print(\"Unable to load data: \\(error)\")\n        \/\/}\n        \/\/image = NSImage.init(data: imageData)\n        \/\/mapsButton.setBackgroundImage(image, for: .normal)\n<br \/>\n        mapsButton.bezelStyle = .texturedSquare\n        mapsButton.isBordered = false \/\/Important\n        mapsButton.wantsLayer = true\n        mapsButton.layer?.backgroundColor = NSColor.systemPink.cgColor\n<br \/>\n        \/\/ rightCalloutAccessoryView = mapsButton\n<br \/>      \n        \/\/ 2\n      markerTintColor = artwork.markerTintColor\n      if let letter = artwork.art_type?.first {\n          if (letter == \"M\") {\n          if let lettertwo = artwork.art_type {\n          if (lettertwo == \"Monument\") {\n          glyphText = \"\ufe0f&#127963;\"\n          } else {\n          glyphText = \"&#127912;\"\n          }\n          } else {\n          glyphText = String(letter)\n          }\n          } else if (letter == \"P\") {\n          glyphText = \"&#128219;\"\n          } else if (letter == \"A\") {\n          glyphText = \"\ufe0f&#128444;\"\n          } else if (letter == \"S\") {\n          glyphText = \"&#128509;\"\n          } else if (letter == \"F\") {\n          glyphText = \"&#9970;\"\n          } else {\n          glyphText = String(letter)\n          }\n      }\n<br \/>\n      let detailLabel = NSTextField()\n      \/\/detailLabel.numberOfLines = 0\n      \/\/detailLabel.font = detailLabel.font.withSize(12)\n      detailLabel.maximumNumberOfLines = 2\n      detailLabel.stringValue = \"\"\n      if (artwork.subtitle != nil) {\n          detailLabel.stringValue = artwork.subtitle! }\n<br \/>        \n      \/\/ detailCalloutAccessoryView = detailLabel\n<br \/>        \n    }\n  }\n}\n<br \/>\nclass Artwork: NSObject, MKAnnotation {\n  let title: String?\n  let locationName: String?\n  let art_type: String?\n  let coordinate: CLLocationCoordinate2D\n  let image: NSImage?\n<br \/>    \n  var markerTintColor: NSColor  {\n      switch art_type {\n      case \"Monument\":\n        return .red\n      case \"Mural\":\n        return .cyan\n      case \"Plaque\":\n        return .blue\n      case \"Fountain\":\n        return .yellow\n      case \"Sculpture\":\n        return .purple\n      case \"Art\":\n        return .magenta\n      default:\n        return .green\n      }\n  }\n<br \/>    \n  init(\n    title: String?,\n    locationName: String?,\n    art_type: String?,\n    coordinate: CLLocationCoordinate2D,\n    image: NSImage?\n  ) {\n    self.title = title\n    self.locationName = locationName\n    self.art_type = art_type\n    self.coordinate = coordinate\n    self.image = nil\n<br \/>\n    super.init()\n  }\n<br \/>\n    init?(feature: MKGeoJSONFeature) {\n      \/\/ 1\n      guard\n        let point = feature.geometry.first as? MKPointAnnotation,\n        let propertiesData = feature.properties,\n        let json = try? JSONSerialization.jsonObject(with: propertiesData),\n        let properties = json as? [String: Any]\n        else {\n          return nil\n      }\n<br \/>\n      \/\/ 3\n      title = properties[\"name\"] as? String\n      locationName = properties[\"descriptio\"] as? String\n      art_type = properties[\"art_type\"] as? String\n      coordinate = point.coordinate\n      image =  nil\n      super.init()\n    }\n<br \/>    \n  var subtitle: String? {\n    return locationName\n  }\n}\n<br \/>\nclass Port: NSObject, MKAnnotation {\n  let title: String?\n  let locationName: String?\n  let port_type: String?\n  let coordinate: CLLocationCoordinate2D\n<br \/>\n  var markerTintColor: NSColor  {\n      switch port_type {\n      case \"Port\":\n        return .red\n      default:\n        return .green\n      }\n  }\n<br \/>\n  init(\n    title: String?,\n    locationName: String?,\n    port_type: String?,\n    coordinate: CLLocationCoordinate2D\n  ) {\n    self.title = title\n    self.locationName = locationName\n    self.port_type = port_type\n    self.coordinate = coordinate\n<br \/>\n    super.init()\n  }\n<br \/>\n    init?(feature: MKGeoJSONFeature) {\n      \/\/ 1\n      guard\n        let point = feature.geometry.first as? MKPointAnnotation,\n        let propertiesData = feature.properties,\n        let json = try? JSONSerialization.jsonObject(with: propertiesData),\n        let properties = json as? [String: Any]\n        else {\n          return nil\n      }\n<br \/>\n      \/\/ 3\n      title = properties[\"name\"] as? String\n      locationName = properties[\"website\"] as? String\n      port_type = properties[\"feature_class\"] as? String\n      coordinate = point.coordinate\n      super.init()\n    }\n<br \/>    \n  var subtitle: String? {\n    return locationName\n  }\n}\n<br \/>\nprivate func loadInitialData() {\n  \/\/ 1\n  guard\n    let fileName = Bundle.main.url(forResource: \"PublicArt\", withExtension: \"geojson\"),\n    let artworkData = try? Data(contentsOf: fileName)\n    else {\n     return\n  }\n<br \/>\n  do {\n    \/\/ 2\n    let features = try MKGeoJSONDecoder()\n      .decode(artworkData)\n      .compactMap { $0 as? MKGeoJSONFeature }\n    \/\/ 3\n    let validWorks = features.compactMap(Artwork.init)\n    \/\/ 4\n    artworks.append(contentsOf: validWorks)\n  } catch {\n    \/\/ 5\n    print(\"Unexpected error: \\(error).\")\n  }\n}\n<br \/>\nprivate func loadNextData() {\n  \/\/ 1\n  guard\n    let fileName = Bundle.main.url(forResource: \"map\", withExtension: \"geojson\"),\n    let portData = try? Data(contentsOf: fileName)\n    else {\n     return\n  }\n<br \/>\n  do {\n    \/\/ 2\n    let features = try MKGeoJSONDecoder()\n      .decode(portData)\n      .compactMap { $0 as? MKGeoJSONFeature }\n    \/\/ 3\n    let validWorks = features.compactMap(Port.init)\n    \/\/ 4\n    ports.append(contentsOf: validWorks)\n  } catch {\n    \/\/ 5\n    print(\"Unexpected error: \\(error).\")\n  }\n}\n<br \/>\nlet chatswoodCoordinates = CLLocationCoordinate2DMake(-33.8009948,151.1664372)\n<br \/>\n\/\/ Now let's create a MKMapView\nlet mapView = MKMapView(frame: CGRect(x:0, y:0, width:800, height:800))\n<br \/>\n\/\/ Define a region for our map view\nvar mapRegion = MKCoordinateRegion()\n<br \/>\nlet mapRegionSpan = 0.001\nmapRegion.center = chatswoodCoordinates\nmapRegion.span.latitudeDelta = mapRegionSpan\nmapRegion.span.longitudeDelta = mapRegionSpan\n<br \/>\nmapView.setRegion(mapRegion, animated: true)\n<br \/>\n\/\/ Create a map annotation\nlet annotation = MKPointAnnotation()\nannotation.coordinate = chatswoodCoordinates\nannotation.title = \"Chatswood\"\nannotation.subtitle = \"Greville\"\n<br \/>\nmapView.addAnnotation(annotation)\n<br \/>\n\/\/ Show artwork on map\nlet artwork = Artwork(\n  title: \"The Cheesetree\",\n  locationName: \"Santa Clause Lane\",\n  art_type: \"Nature, like\",\n  coordinate: CLLocationCoordinate2D(latitude: -33.8010376, longitude: 151.1663819),\n  image: nil)\n<br \/>\nmapView.addAnnotation(artwork)\n<br \/>\nloadInitialData()\nmapView.addAnnotations(artworks)\n<br \/>\nloadNextData()\nmapView.addAnnotations(ports)\n<br \/>\nmapView.register(\n  ArtworkMarkerView.self,\n  forAnnotationViewWithReuseIdentifier:\n    MKMapViewDefaultAnnotationViewReuseIdentifier)\n<br \/>\n\/\/ Add the created mapView to our Playground Live View\nPlaygroundPage.current.liveView = mapView\n<\/code>\n\n<!--p>You can also see this play out at WordPress 4.1.1's <a target=\"_blank\" href='\/\/www.rjmprogramming.com.au\/ITblog\/new-swift-playgrounds-on-macos-map-emoji-tutorial\/' rel=\"noopener\">Swift Playgrounds on macOS Map Emoji Tutorial<\/a>.<\/p-->\n<hr>\n<p id='sposmgjt'>Previous relevant <a target=\"_blank\" title='Swift Playgrounds on macOS Map GeoJson Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/swift-playgrounds-on-macos-map-geojson-tutorial\/' rel=\"noopener\">Swift Playgrounds on macOS Map GeoJson Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_geojson_playground.gif\" rel=\"noopener\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Swift Playgrounds on macOS Map GeoJson Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_geojson_playground.gif\" title=\"Swift Playgrounds on macOS Map GeoJson Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Swift Playgrounds on macOS Map GeoJson Tutorial<\/p><\/div>\n<p>Before we leave the &#8230;<\/p>\n<ul>\n<li><a target=\"_blank\" title='Xcode IDE information from Apple' href='https:\/\/developer.apple.com\/technologies\/tools\/' rel=\"noopener\">Xcode<\/a> on macOS &#8230;<\/li>\n<li>File -&gt; New -&gt; Playground&#8230;<\/li>\n<li>Map<\/li>\n<li>Next<\/li>\n<li>Create<\/li>\n<\/ul>\n<p> &#8230; &#8220;where<font size=1> of life<\/font>&#8221; <a target=\"_blank\" title='Google Maps' href='http:\/\/maps.google.com' rel=\"noopener\">Google Maps<\/a> or <a target=\"_blank\" title='Apple Maps' href='https:\/\/developer.apple.com\/maps\/' rel=\"noopener\">Apple Maps<\/a> ideas of yesterday&#8217;s <a title='Swift Playgrounds on macOS Map Tutorial' href='#sposmt'>Swift Playgrounds on macOS Map Tutorial<\/a> we wanted to further take in the excellence of the advice of <a target=\"_blank\" href='https:\/\/www.kodeco.com\/7738344-mapkit-tutorial-getting-started' title='MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com' rel=\"noopener\">MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com<\/a> and delve into the &#8230;<\/p>\n<ul>\n<li>involvement of public GeoJson PublicArt examples (ours being Geelong &#8230; so if you zoom out to southern Victoria and back in on the colourful colour coded new pins representing Geelong PublicArt locations) &#8230; in conjunction with &#8230;<\/li>\n<li>MKGeoJSONDecoder (to decode GeoJSON data)<\/li>\n<\/ul>\n<p> &#8230; is a great approach to Customising Annotations on your Swift Playground Map desktop application, via Xcode as you can see with <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/MyPlayground.swift-GETME\" title=\"MyPlayground.swift\" rel=\"noopener\">our changed<\/a> <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/MyPlayground.swift-GETME\" title=\"MyPlayground.swift\" rel=\"noopener\">MyPlayground.swift<\/a> Swift source code macOS Swift desktop application code &#8230;<\/p>\n<p><code><br \/>\n\/\/: A MapKit based Playground<br \/>\n<br \/>\nimport PlaygroundSupport<br \/>\nimport MapKit<br \/>\n<br \/>\nprivate var artworks: [Artwork] = []<br \/>\n<br \/>\nclass ArtworkMarkerView: MKMarkerAnnotationView {<br \/>\n  override var annotation: MKAnnotation? {<br \/>\n    willSet {<br \/>\n      \/\/ 1<br \/>\n      guard let artwork = newValue as? Artwork else {<br \/>\n        return<br \/>\n      }<br \/>\n      canShowCallout = true<br \/>\n      calloutOffset = CGPoint(x: -5, y: 5)<br \/>\n      \/\/rightCalloutAccessoryView = UIButton(type:<br \/>\n      \/\/          .detailDisclosure)<br \/>\n<br \/>\n      \/\/ 2<br \/>\n      markerTintColor = artwork.markerTintColor<br \/>\n      if let letter = artwork.art_type?.first {<br \/>\n        glyphText = String(letter)<br \/>\n      }<br \/>\n    }<br \/>\n  }<br \/>\n}<br \/>\n<br \/>\nclass Artwork: NSObject, MKAnnotation {<br \/>\n  let title: String?<br \/>\n  let locationName: String?<br \/>\n  let art_type: String?<br \/>\n  let coordinate: CLLocationCoordinate2D<br \/>\n<br \/> <br \/>\n  var markerTintColor: NSColor  {<br \/>\n      switch art_type {<br \/>\n      case \"Monument\":<br \/>\n        return .red<br \/>\n      case \"Mural\":<br \/>\n        return .cyan<br \/>\n      case \"Plaque\":<br \/>\n        return .blue<br \/>\n      case \"Fountain\":<br \/>\n        return .yellow<br \/>\n      case \"Sculpture\":<br \/>\n        return .purple<br \/>\n      case \"Art\":<br \/>\n        return .magenta<br \/>\n      default:<br \/>\n        return .green<br \/>\n      }<br \/>\n  }<br \/>\n<br \/> <br \/>\n  init(<br \/>\n    title: String?,<br \/>\n    locationName: String?,<br \/>\n    art_type: String?,<br \/>\n    coordinate: CLLocationCoordinate2D<br \/>\n  ) {<br \/>\n    self.title = title<br \/>\n    self.locationName = locationName<br \/>\n    self.art_type = art_type<br \/>\n    self.coordinate = coordinate<br \/>\n<br \/>\n    super.init()<br \/>\n  }<br \/>\n<br \/>\n    init?(feature: MKGeoJSONFeature) {<br \/>\n      \/\/ 1<br \/>\n      guard<br \/>\n        let point = feature.geometry.first as? MKPointAnnotation,<br \/>\n        let propertiesData = feature.properties,<br \/>\n        let json = try? JSONSerialization.jsonObject(with: propertiesData),<br \/>\n        let properties = json as? [String: Any]<br \/>\n        else {<br \/>\n          return nil<br \/>\n      }<br \/>\n<br \/>\n      \/\/ 3<br \/>\n      title = properties[\"name\"] as? String<br \/>\n      locationName = properties[\"descriptio\"] as? String<br \/>\n      art_type = properties[\"art_type\"] as? String<br \/>\n      coordinate = point.coordinate<br \/>\n      super.init()<br \/>\n    }<br \/>\n<br \/> <br \/>\n  var subtitle: String? {<br \/>\n    return locationName<br \/>\n  }<br \/>\n}<br \/>\n<br \/>\nprivate func loadInitialData() {<br \/>\n  \/\/ 1<br \/>\n  guard<br \/>\n    let fileName = Bundle.main.url(forResource: \"PublicArt\", withExtension: \"geojson\"),<br \/>\n    let artworkData = try? Data(contentsOf: fileName)<br \/>\n    else {<br \/>\n     return<br \/>\n  }<br \/>\n<br \/>\n  do {<br \/>\n    \/\/ 2<br \/>\n    let features = try MKGeoJSONDecoder()<br \/>\n      .decode(artworkData)<br \/>\n      .compactMap { $0 as? MKGeoJSONFeature }<br \/>\n    \/\/ 3<br \/>\n    let validWorks = features.compactMap(Artwork.init)<br \/>\n    \/\/ 4<br \/>\n    artworks.append(contentsOf: validWorks)<br \/>\n  } catch {<br \/>\n    \/\/ 5<br \/>\n    print(\"Unexpected error: \\(error).\")<br \/>\n  }<br \/>\n}<br \/>\n<br \/>\nlet chatswoodCoordinates = CLLocationCoordinate2DMake(-33.8009948,151.1664372)<br \/>\n<br \/>\n\/\/ Now let's create a MKMapView<br \/>\nlet mapView = MKMapView(frame: CGRect(x:0, y:0, width:800, height:800))<br \/>\n<br \/>\n\/\/ Define a region for our map view<br \/>\nvar mapRegion = MKCoordinateRegion()<br \/>\n<br \/>\nlet mapRegionSpan = 0.001<br \/>\nmapRegion.center = chatswoodCoordinates<br \/>\nmapRegion.span.latitudeDelta = mapRegionSpan<br \/>\nmapRegion.span.longitudeDelta = mapRegionSpan<br \/>\n<br \/>\nmapView.setRegion(mapRegion, animated: true)<br \/>\n<br \/>\n\/\/ Create a map annotation<br \/>\nlet annotation = MKPointAnnotation()<br \/>\nannotation.coordinate = chatswoodCoordinates<br \/>\nannotation.title = \"Chatswood\"<br \/>\nannotation.subtitle = \"Greville\"<br \/>\n<br \/>\nmapView.addAnnotation(annotation)<br \/>\n<br \/>\n\/\/ Show artwork on map<br \/>\nlet artwork = Artwork(<br \/>\n  title: \"The Cheesetree\",<br \/>\n  locationName: \"Santa Clause Lane\",<br \/>\n  art_type: \"Nature, like\",<br \/>\n  coordinate: CLLocationCoordinate2D(latitude: -33.8010376, longitude: 151.1663819))<br \/>\n<br \/>\nmapView.addAnnotation(artwork)<br \/>\n<br \/>\nloadInitialData()<br \/>\nmapView.addAnnotations(artworks)<br \/>\n<br \/>\nmapView.register(<br \/>\n  ArtworkMarkerView.self,<br \/>\n  forAnnotationViewWithReuseIdentifier:<br \/>\n    MKMapViewDefaultAnnotationViewReuseIdentifier)<br \/>\n<br \/>\n\/\/ Add the created mapView to our Playground Live View<br \/>\nPlaygroundPage.current.liveView = mapView<br \/>\n<\/code><\/p>\n<p> &#8230; that goes along with our adding into our Playground project&#8217;s Resources a file called PublicArt.geojson downloaded via <a target=\"_blank\" title='Geelong PublicArt.geojson, thanks' href='https:\/\/data.gov.au\/dataset\/ds-dga-cff8c6aa-8ed4-4562-987b-cacc728eb914\/details' rel=\"noopener\">this webpage<\/a>, thanks everybody!<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=\"_blank\" href='\/\/www.rjmprogramming.com.au\/ITblog\/swift-playgrounds-on-macos-map-geojson-tutorial\/' rel=\"noopener\">Swift Playgrounds on macOS Map GeoJson Tutorial<\/a>.<\/p-->\n<hr>\n<p id='sposmt'>Previous relevant <a target=\"_blank\" title='Swift Playgrounds on macOS Map Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/swift-playgrounds-on-macos-map-tutorial\/' rel=\"noopener\">Swift Playgrounds on macOS Map Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_new_playground.gif\" rel=\"noopener\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Swift Playgrounds on macOS Map Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/swift_new_playground.gif\" title=\"Swift Playgrounds on macOS Map Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Swift Playgrounds on macOS Map Tutorial<\/p><\/div>\n<p>Are you looking for &#8230;<\/p>\n<ul>\n<li>informal &#8230; but &#8230;<\/li>\n<li><a target=\"_blank\" title='Integrated Development Environment information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Integrated_development_environment' rel=\"noopener\">IDE<\/a> based compiling &#8230;<\/li>\n<li>Swift &#8230; code based &#8230;<\/li>\n<li>macOS or iOS &#8230; suiting &#8230;<\/li>\n<\/ul>\n<p> &#8230; programming environment?   How about, if you are into the &#8220;where of&#8221; in life &#8230;<\/p>\n<ul>\n<li><a target=\"_blank\" title='Xcode IDE information from Apple' href='https:\/\/developer.apple.com\/technologies\/tools\/' rel=\"noopener\">Xcode<\/a> on macOS &#8230;<\/li>\n<li>File -&gt; New -&gt; Playground&#8230;<\/li>\n<li>Map<\/li>\n<li>Next<\/li>\n<li>Create<\/li>\n<\/ul>\n<p>Now, by informal, we mean you don&#8217;t have to worry about Development or Deployment certificates, and all that jazz.  You just get to &#8220;play around&#8221;, make mistakes, take advice, and learn (more, on top of tutorials like <a title='Swift Playgrounds on iPad Primer Tutorial' href='#spppt'>Swift Playgrounds on iPad Primer Tutorial<\/a>) about Swift programming language, in the process!<\/p>\n<p>We had fun producing a macOS Swift playground desktop application that featured one local &#8220;Artwork&#8221; class (default) pin<font size=1>ning<\/font> map item, thanks to the great advice from <a target=\"_blank\" href='https:\/\/www.kodeco.com\/7738344-mapkit-tutorial-getting-started' title='MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com' rel=\"noopener\">MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com<\/a> &#8230; thanks.  We ended up with &#8230;<\/p>\n<p><code><br \/>\n\/\/: A MapKit based Playground<br \/>\n<br \/>\nimport MapKit<br \/>\nimport PlaygroundSupport<br \/>\n<br \/>\nclass Artwork: NSObject, MKAnnotation {<br \/>\n  let title: String?<br \/>\n  let locationName: String?<br \/>\n  let discipline: String?<br \/>\n  let coordinate: CLLocationCoordinate2D<br \/>\n<br \/>\n  init(<br \/>\n    title: String?,<br \/>\n    locationName: String?,<br \/>\n    discipline: String?,<br \/>\n    coordinate: CLLocationCoordinate2D<br \/>\n  ) {<br \/>\n    self.title = title<br \/>\n    self.locationName = locationName<br \/>\n    self.discipline = discipline<br \/>\n    self.coordinate = coordinate<br \/>\n<br \/>\n    super.init()<br \/>\n  }<br \/>\n<br \/>\n  var subtitle: String? {<br \/>\n    return locationName<br \/>\n  }<br \/>\n}<br \/>\n<br \/>\nlet chatswoodCoordinates = CLLocationCoordinate2DMake(-33.8009948,151.1664372)<br \/>\n<br \/>\n\/\/ Now let's create a MKMapView<br \/>\nlet mapView = MKMapView(frame: CGRect(x:0, y:0, width:800, height:800))<br \/>\n<br \/>\n\/\/ Define a region for our map view<br \/>\nvar mapRegion = MKCoordinateRegion()<br \/>\n<br \/>\nlet mapRegionSpan = 0.001<br \/>\nmapRegion.center = chatswoodCoordinates<br \/>\nmapRegion.span.latitudeDelta = mapRegionSpan<br \/>\nmapRegion.span.longitudeDelta = mapRegionSpan<br \/>\n<br \/>\nmapView.setRegion(mapRegion, animated: true)<br \/>\n<br \/>\n\/\/ Create a map annotation<br \/>\nlet annotation = MKPointAnnotation()<br \/>\nannotation.coordinate = chatswoodCoordinates<br \/>\nannotation.title = \"Chatswood\"<br \/>\nannotation.subtitle = \"Greville\"<br \/>\n<br \/>\nmapView.addAnnotation(annotation)<br \/>\n<br \/>\n\/\/ Show artwork on map<br \/>\nlet artwork = Artwork(<br \/>\n  title: \"The Cheesetree\",<br \/>\n  locationName: \"Santa Clause Lane\",<br \/>\n  discipline: \"Nature, like\",<br \/>\n  coordinate: CLLocationCoordinate2D(latitude: -33.8010376, longitude: 151.1663819))<br \/>\n<br \/>\nmapView.addAnnotation(artwork)<br \/>\n<br \/>\n\/\/ Add the created mapView to our Playground Live View<br \/>\nPlaygroundPage.current.liveView = mapView<br \/>\n<\/code><\/p>\n<p> &#8230; in <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Xcode\/MyPlayground.swift_GETME\" title=\"MyPlayground.swift\" rel=\"noopener\">MyPlayground.swift<\/a> Swift source code macOS Swift desktop application code.<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=\"_blank\" href='\/\/www.rjmprogramming.com.au\/ITblog\/new-swift-playgrounds-on-ipad-primer-tutorial\/' rel=\"noopener\">Swift Playgrounds on iPad Primer Tutorial<\/a>.<\/p-->\n<hr>\n<p id='spppt'>Previous relevant <a target=\"_blank\" title='Swift Playgrounds on iPad Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/swift-playgrounds-on-ipad-primer-tutorial\/' rel=\"noopener\">Swift Playgrounds on iPad Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/ipad_ide.pdf\" rel=\"noopener\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Swift Playgrounds on iPad Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/ipad_ide.jpg\" title=\"Swift Playgrounds on iPad Primer Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">Swift Playgrounds on iPad Primer Tutorial<\/p><\/div>\n<p>Generally speaking around here, we tend to think you need at least a laptop (eg. MacBook Pro) or desktop computer PC (macOS or Windows) or Linux operating system arrangement, to (computer) program <font size=1>(in other words, the iOS operating system is a missing part of the equation here)<\/font>.  That has led us to <a target=\"_blank\" title='?' href='https:\/\/adventuresinjournalism.substack.com\/p\/check-yourself' rel=\"noopener\"><i>ass<\/i>u<b>me<\/b><\/a> more than we know, though looking into this topic via our <a target=\"_blank\" title='Google' href='https:\/\/google.com' rel=\"noopener\">Google<\/a> search of &#8230;<\/p>\n<p><code><br \/>\n<a target=\"_blank\" title='ide for ipad' href='https:\/\/www.google.com\/search?q=ide+for+ipad&#038;rlz=1C5CHFA_enAU832AU832&#038;oq=ide+for+ipad&#038;aqs=chrome..69i57j0l3j0i395j0i22i30i395l5.3429j1j4&#038;sourceid=chrome&#038;ie=UTF-8' rel=\"noopener\">ide for ipad<\/a><br \/>\n<\/code><\/p>\n<p> &#8230; had us first looking into Python via &#8220;pythonista&#8221;, but the $14.99 price tag was far too much for us to absorb so early in the morning, and a warning that exclusive &#8220;above the fold&#8221; reading can have you suffer from (FOMO) &#8220;fear of missing out&#8221; syndrome.  Reading, then, below the fold, soon turned up the <a target=\"_blank\" title='Xcode information from Apple' href='https:\/\/developer.apple.com\/xcode\/' rel=\"noopener\">Xcode<\/a> IDE (we have on macOS, here, and appears &#8220;above the fold&#8221; regarding blurb actions above) programming language of choice, Swift, with its <a target=\"_blank\" title='Apple' href='https:\/\/apple.com' rel=\"noopener\">Apple<\/a> iPad place &#8230;<\/p>\n<p><code><br \/>\n<a target=\"_blank\" title='Swift Playgrounds' href='https:\/\/www.apple.com\/au\/swift\/playgrounds\/' rel=\"noopener\">Swift Playgrounds<\/a><br \/>\n<\/code><\/p>\n<p> &#8230; as a great resource into programming and &#8220;robotics feeling&#8221; coding leading to &#8220;programming action&#8221;!   And the presentation may well suit young&#8217;uns getting into programming early, if that&#8217;s why you are reading this blog posting.  As Swift Playgrounds starts out intimating, to &#8220;follow a recipe&#8221; and perform &#8220;steps in order&#8221; is likely to lead to the happiest programming and coding experience <font size=1>(to put it mildly &#8230; or &#8230; <\/font><font size=6>just follow orders<\/font><font size=4> &#8230; initially<\/font><font size=2> &#8230; to put it more bluntly<\/font><font size=1>)<\/font>.<\/p>\n<p>Curiosity is the big key here.  Start this way, and invariably if it interests, it interests, and could lead to many other avenues of knowledge, and it involving the Swift computer language, that could be a lead in to iOS mobile app development via Xcode and (paying, or not) careers in Information Technology?!<\/p>\n<p>Or perhaps you are on an iPad and wish to fork out the $14.99 and get into Python, then that would be <a target=\"_blank\" title='?' href='https:\/\/www.youtube.com\/watch?v=krD4hdGvGHM' rel=\"noopener\">interesting<\/a> too, we have no doubt.  Either way, see how we R&#038;D<font size=1>&#8216;ed<\/font> this topic, on an iPad, with today&#8217;s <a target=\"_blank\" href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/iPad\/ipad_ide.pdf\" title=\"Click picture\" rel=\"noopener\">PDF presentation<\/a> <font size=1>(dare we say)<\/font> <font size=4>following orders<\/font>.<\/p>\n<p>We&#8217;ve also heard, but have not researched this, that Apple is making changes with iPad products into the future, to improve their programming capacities.  Stay tuned, <a onclick=\"alert('We shall still be striking an assume macOS pose!  For now.');\" style=\"cursor:pointer;text-decoration:underline;\">with Apple<\/a>, on that.<\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d51031' onclick='var dv=document.getElementById(\"d51031\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/ipad\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d51031' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d57904' onclick='var dv=document.getElementById(\"d57904\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/swift\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d57904' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d57921' onclick='var dv=document.getElementById(\"d57921\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/json\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d57921' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d57927' onclick='var dv=document.getElementById(\"d57927\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/emoji\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d57927' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d75259' onclick='var dv=document.getElementById(\"d75259\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/xcode\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d75259' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>With a newer version of macOS Xcode Version 26.6 (17F113), we&#8217;re revisiting the &#8230; New -&gt; Playground&#8230; -&gt; Map &#8230; concepts developed upon with Swift Playgrounds on macOS Map Emoji Tutorial. This time around the motivation is different, and that &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/swift-playgrounds-on-macos-map-revisit-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,31,37,40],"tags":[3910,481,585,678,684,5758,719,2178,745,2819,4190,997,1080,1227,1319,3171,1473],"class_list":["post-75259","post","type-post","status-publish","format-standard","hentry","category-elearning","category-projects","category-tutorials","category-xcode","tag-execute","tag-geographicals","tag-ide","tag-label","tag-latitude","tag-launch","tag-longitude","tag-macos","tag-map","tag-pin","tag-playground","tag-programming","tag-run","tag-swift","tag-tutorial","tag-workflow","tag-xcode"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/75259"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=75259"}],"version-history":[{"count":5,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/75259\/revisions"}],"predecessor-version":[{"id":75264,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/75259\/revisions\/75264"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=75259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=75259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=75259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}