Swift Playgrounds on macOS Map Emoji Tutorial

Swift Playgrounds on macOS Map Emoji Tutorial

Swift Playgrounds on macOS Map Emoji Tutorial

We find work in the Google Maps or Apple Maps style of related “where of life” development work has you reaching for more and more layers of functionality, but we want to draw a line in the sand at …

  • using emojis even before any pin clicking, rather than …
  • any NSImage or UIImage image interventions further down the “clicking” track …
  • 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)

… even though the great MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com gave us lots of ideas in this line of thinking and trying. So, further to yesterday’s Swift Playgrounds on macOS Map GeoJson Tutorial‘s progress, today …

  • we add another “map.geojson” Ports (around the world) data source idea into the Playground’s Resources folder, we thank geojson.xyz for … and we …
  • 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

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 our changed MyPlayground.swift Swift source code macOS Swift desktop application code …


//: A MapKit based Playground

import PlaygroundSupport
import AppKit
import Cocoa
import MapKit

private var artworks: [Artwork] = []
private var ports: [Port] = []
private var rightCalloutAccessoryView: [NSView]
public var nsg: [NSString]
//public var imageURL: [URL?]
//public var imageData: [Data]

// imageURL = [NSURL URLWithString:@"file:///Applications/MAMP/htdocs/swift_map_more-2.jpg"]
//let imageURL =
//NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first?.URLByAppendingPathComponent("swift_map_more-2.jpg")

class ViewController: NSViewController {

@objc
func printSomething() {
print("Hello")
}

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
let myButtonRect = CGRect(x: 10, y: 10, width: 100, height: 10)
let myButton = NSButton(frame: myButtonRect)
view.addSubview(myButton)

myButton.target = self
myButton.action = #selector(ViewController.printSomething)
}

//override var representedObject: AnyObject? {
// didSet {
// Update the view, if already loaded.
// }
// }
}

class ArtworkView: MKAnnotationView {
override var annotation: MKAnnotation? {
willSet {
guard let artwork = newValue as? Artwork else {
return
}

canShowCallout = true
calloutOffset = CGPoint(x: -5, y: 5)
let theButton: NSButton = NSButton()
theButton.setButtonType(NSButton.ButtonType.pushOnPushOff)

rightCalloutAccessoryView = theButton

image = artwork.image
}
}
}

class ArtworkMarkerView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
// 1
var i = 22247
guard let artwork = newValue as? Artwork else {
return
}
canShowCallout = true
calloutOffset = CGPoint(x: -5, y: 5)

//rightCalloutAccessoryView = NSButton(type: .detailDisclosure)
let mapsButton: NSButton = NSButton()
mapsButton.setButtonType(NSButton.ButtonType.pushOnPushOff)
// Insert code here to initialize your application
//self.imageView.image = image;
// initialise your image object with the image data
//do {
// let imageData = try Data(contentsOf: imageURL)
// image = NSImage.init(data: imageData)
//} catch {
// print("Unable to load data: \(error)")
//}
//image = NSImage.init(data: imageData)
//mapsButton.setBackgroundImage(image, for: .normal)

mapsButton.bezelStyle = .texturedSquare
mapsButton.isBordered = false //Important
mapsButton.wantsLayer = true
mapsButton.layer?.backgroundColor = NSColor.systemPink.cgColor

// rightCalloutAccessoryView = mapsButton


// 2
markerTintColor = artwork.markerTintColor
if let letter = artwork.art_type?.first {
if (letter == "M") {
if let lettertwo = artwork.art_type {
if (lettertwo == "Monument") {
glyphText = "️🏛"
} else {
glyphText = "🎨"
}
} else {
glyphText = String(letter)
}
} else if (letter == "P") {
glyphText = "📛"
} else if (letter == "A") {
glyphText = "️🖼"
} else if (letter == "S") {
glyphText = "🗽"
} else if (letter == "F") {
glyphText = "⛲"
} else {
glyphText = String(letter)
}
}

let detailLabel = NSTextField()
//detailLabel.numberOfLines = 0
//detailLabel.font = detailLabel.font.withSize(12)
detailLabel.maximumNumberOfLines = 2
detailLabel.stringValue = ""
if (artwork.subtitle != nil) {
detailLabel.stringValue = artwork.subtitle! }


// detailCalloutAccessoryView = detailLabel


}
}
}

class Artwork: NSObject, MKAnnotation {
let title: String?
let locationName: String?
let art_type: String?
let coordinate: CLLocationCoordinate2D
let image: NSImage?


var markerTintColor: NSColor {
switch art_type {
case "Monument":
return .red
case "Mural":
return .cyan
case "Plaque":
return .blue
case "Fountain":
return .yellow
case "Sculpture":
return .purple
case "Art":
return .magenta
default:
return .green
}
}


init(
title: String?,
locationName: String?,
art_type: String?,
coordinate: CLLocationCoordinate2D,
image: NSImage?
) {
self.title = title
self.locationName = locationName
self.art_type = art_type
self.coordinate = coordinate
self.image = nil

super.init()
}

init?(feature: MKGeoJSONFeature) {
// 1
guard
let point = feature.geometry.first as? MKPointAnnotation,
let propertiesData = feature.properties,
let json = try? JSONSerialization.jsonObject(with: propertiesData),
let properties = json as? [String: Any]
else {
return nil
}

// 3
title = properties["name"] as? String
locationName = properties["descriptio"] as? String
art_type = properties["art_type"] as? String
coordinate = point.coordinate
image = nil
super.init()
}


var subtitle: String? {
return locationName
}
}

class Port: NSObject, MKAnnotation {
let title: String?
let locationName: String?
let port_type: String?
let coordinate: CLLocationCoordinate2D

var markerTintColor: NSColor {
switch port_type {
case "Port":
return .red
default:
return .green
}
}

init(
title: String?,
locationName: String?,
port_type: String?,
coordinate: CLLocationCoordinate2D
) {
self.title = title
self.locationName = locationName
self.port_type = port_type
self.coordinate = coordinate

super.init()
}

init?(feature: MKGeoJSONFeature) {
// 1
guard
let point = feature.geometry.first as? MKPointAnnotation,
let propertiesData = feature.properties,
let json = try? JSONSerialization.jsonObject(with: propertiesData),
let properties = json as? [String: Any]
else {
return nil
}

// 3
title = properties["name"] as? String
locationName = properties["website"] as? String
port_type = properties["feature_class"] as? String
coordinate = point.coordinate
super.init()
}


var subtitle: String? {
return locationName
}
}

private func loadInitialData() {
// 1
guard
let fileName = Bundle.main.url(forResource: "PublicArt", withExtension: "geojson"),
let artworkData = try? Data(contentsOf: fileName)
else {
return
}

do {
// 2
let features = try MKGeoJSONDecoder()
.decode(artworkData)
.compactMap { $0 as? MKGeoJSONFeature }
// 3
let validWorks = features.compactMap(Artwork.init)
// 4
artworks.append(contentsOf: validWorks)
} catch {
// 5
print("Unexpected error: \(error).")
}
}

private func loadNextData() {
// 1
guard
let fileName = Bundle.main.url(forResource: "map", withExtension: "geojson"),
let portData = try? Data(contentsOf: fileName)
else {
return
}

do {
// 2
let features = try MKGeoJSONDecoder()
.decode(portData)
.compactMap { $0 as? MKGeoJSONFeature }
// 3
let validWorks = features.compactMap(Port.init)
// 4
ports.append(contentsOf: validWorks)
} catch {
// 5
print("Unexpected error: \(error).")
}
}

let chatswoodCoordinates = CLLocationCoordinate2DMake(-33.8009948,151.1664372)

// Now let's create a MKMapView
let mapView = MKMapView(frame: CGRect(x:0, y:0, width:800, height:800))

// Define a region for our map view
var mapRegion = MKCoordinateRegion()

let mapRegionSpan = 0.001
mapRegion.center = chatswoodCoordinates
mapRegion.span.latitudeDelta = mapRegionSpan
mapRegion.span.longitudeDelta = mapRegionSpan

mapView.setRegion(mapRegion, animated: true)

// Create a map annotation
let annotation = MKPointAnnotation()
annotation.coordinate = chatswoodCoordinates
annotation.title = "Chatswood"
annotation.subtitle = "Greville"

mapView.addAnnotation(annotation)

// Show artwork on map
let artwork = Artwork(
title: "The Cheesetree",
locationName: "Santa Clause Lane",
art_type: "Nature, like",
coordinate: CLLocationCoordinate2D(latitude: -33.8010376, longitude: 151.1663819),
image: nil)

mapView.addAnnotation(artwork)

loadInitialData()
mapView.addAnnotations(artworks)

loadNextData()
mapView.addAnnotations(ports)

mapView.register(
ArtworkMarkerView.self,
forAnnotationViewWithReuseIdentifier:
MKMapViewDefaultAnnotationViewReuseIdentifier)

// Add the created mapView to our Playground Live View
PlaygroundPage.current.liveView = mapView


Previous relevant Swift Playgrounds on macOS Map GeoJson Tutorial is shown below.

Swift Playgrounds on macOS Map GeoJson Tutorial

Swift Playgrounds on macOS Map GeoJson Tutorial

Before we leave the …

  • Xcode on macOS …
  • File -> New -> Playground…
  • Map
  • Next
  • Create

… “where of lifeGoogle Maps or Apple Maps ideas of yesterday’s Swift Playgrounds on macOS Map Tutorial we wanted to further take in the excellence of the advice of MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com and delve into the …

  • involvement of public GeoJson PublicArt examples (ours being Geelong … so if you zoom out to southern Victoria and back in on the colourful colour coded new pins representing Geelong PublicArt locations) … in conjunction with …
  • MKGeoJSONDecoder (to decode GeoJSON data)

… is a great approach to Customising Annotations on your Swift Playground Map desktop application, via Xcode as you can see with our changed MyPlayground.swift Swift source code macOS Swift desktop application code …


//: A MapKit based Playground

import PlaygroundSupport
import MapKit

private var artworks: [Artwork] = []

class ArtworkMarkerView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
// 1
guard let artwork = newValue as? Artwork else {
return
}
canShowCallout = true
calloutOffset = CGPoint(x: -5, y: 5)
//rightCalloutAccessoryView = UIButton(type:
// .detailDisclosure)

// 2
markerTintColor = artwork.markerTintColor
if let letter = artwork.art_type?.first {
glyphText = String(letter)
}
}
}
}

class Artwork: NSObject, MKAnnotation {
let title: String?
let locationName: String?
let art_type: String?
let coordinate: CLLocationCoordinate2D


var markerTintColor: NSColor {
switch art_type {
case "Monument":
return .red
case "Mural":
return .cyan
case "Plaque":
return .blue
case "Fountain":
return .yellow
case "Sculpture":
return .purple
case "Art":
return .magenta
default:
return .green
}
}


init(
title: String?,
locationName: String?,
art_type: String?,
coordinate: CLLocationCoordinate2D
) {
self.title = title
self.locationName = locationName
self.art_type = art_type
self.coordinate = coordinate

super.init()
}

init?(feature: MKGeoJSONFeature) {
// 1
guard
let point = feature.geometry.first as? MKPointAnnotation,
let propertiesData = feature.properties,
let json = try? JSONSerialization.jsonObject(with: propertiesData),
let properties = json as? [String: Any]
else {
return nil
}

// 3
title = properties["name"] as? String
locationName = properties["descriptio"] as? String
art_type = properties["art_type"] as? String
coordinate = point.coordinate
super.init()
}


var subtitle: String? {
return locationName
}
}

private func loadInitialData() {
// 1
guard
let fileName = Bundle.main.url(forResource: "PublicArt", withExtension: "geojson"),
let artworkData = try? Data(contentsOf: fileName)
else {
return
}

do {
// 2
let features = try MKGeoJSONDecoder()
.decode(artworkData)
.compactMap { $0 as? MKGeoJSONFeature }
// 3
let validWorks = features.compactMap(Artwork.init)
// 4
artworks.append(contentsOf: validWorks)
} catch {
// 5
print("Unexpected error: \(error).")
}
}

let chatswoodCoordinates = CLLocationCoordinate2DMake(-33.8009948,151.1664372)

// Now let's create a MKMapView
let mapView = MKMapView(frame: CGRect(x:0, y:0, width:800, height:800))

// Define a region for our map view
var mapRegion = MKCoordinateRegion()

let mapRegionSpan = 0.001
mapRegion.center = chatswoodCoordinates
mapRegion.span.latitudeDelta = mapRegionSpan
mapRegion.span.longitudeDelta = mapRegionSpan

mapView.setRegion(mapRegion, animated: true)

// Create a map annotation
let annotation = MKPointAnnotation()
annotation.coordinate = chatswoodCoordinates
annotation.title = "Chatswood"
annotation.subtitle = "Greville"

mapView.addAnnotation(annotation)

// Show artwork on map
let artwork = Artwork(
title: "The Cheesetree",
locationName: "Santa Clause Lane",
art_type: "Nature, like",
coordinate: CLLocationCoordinate2D(latitude: -33.8010376, longitude: 151.1663819))

mapView.addAnnotation(artwork)

loadInitialData()
mapView.addAnnotations(artworks)

mapView.register(
ArtworkMarkerView.self,
forAnnotationViewWithReuseIdentifier:
MKMapViewDefaultAnnotationViewReuseIdentifier)

// Add the created mapView to our Playground Live View
PlaygroundPage.current.liveView = mapView

… that goes along with our adding into our Playground project’s Resources a file called PublicArt.geojson downloaded via this webpage, thanks everybody!


Previous relevant Swift Playgrounds on macOS Map Tutorial is shown below.

Swift Playgrounds on macOS Map Tutorial

Swift Playgrounds on macOS Map Tutorial

Are you looking for …

  • informal … but …
  • IDE based compiling …
  • Swift … code based …
  • macOS or iOS … suiting …

… programming environment? How about, if you are into the “where of” in life …

  • Xcode on macOS …
  • File -> New -> Playground…
  • Map
  • Next
  • Create

Now, by informal, we mean you don’t have to worry about Development or Deployment certificates, and all that jazz. You just get to “play around”, make mistakes, take advice, and learn (more, on top of tutorials like Swift Playgrounds on iPad Primer Tutorial) about Swift programming language, in the process!

We had fun producing a macOS Swift playground desktop application that featured one local “Artwork” class (default) pinning map item, thanks to the great advice from MapKit Tutorial: Getting Started | Kodeco, the new raywenderlich.com … thanks. We ended up with …


//: A MapKit based Playground

import MapKit
import PlaygroundSupport

class Artwork: NSObject, MKAnnotation {
let title: String?
let locationName: String?
let discipline: String?
let coordinate: CLLocationCoordinate2D

init(
title: String?,
locationName: String?,
discipline: String?,
coordinate: CLLocationCoordinate2D
) {
self.title = title
self.locationName = locationName
self.discipline = discipline
self.coordinate = coordinate

super.init()
}

var subtitle: String? {
return locationName
}
}

let chatswoodCoordinates = CLLocationCoordinate2DMake(-33.8009948,151.1664372)

// Now let's create a MKMapView
let mapView = MKMapView(frame: CGRect(x:0, y:0, width:800, height:800))

// Define a region for our map view
var mapRegion = MKCoordinateRegion()

let mapRegionSpan = 0.001
mapRegion.center = chatswoodCoordinates
mapRegion.span.latitudeDelta = mapRegionSpan
mapRegion.span.longitudeDelta = mapRegionSpan

mapView.setRegion(mapRegion, animated: true)

// Create a map annotation
let annotation = MKPointAnnotation()
annotation.coordinate = chatswoodCoordinates
annotation.title = "Chatswood"
annotation.subtitle = "Greville"

mapView.addAnnotation(annotation)

// Show artwork on map
let artwork = Artwork(
title: "The Cheesetree",
locationName: "Santa Clause Lane",
discipline: "Nature, like",
coordinate: CLLocationCoordinate2D(latitude: -33.8010376, longitude: 151.1663819))

mapView.addAnnotation(artwork)

// Add the created mapView to our Playground Live View
PlaygroundPage.current.liveView = mapView

… in MyPlayground.swift Swift source code macOS Swift desktop application code.


Previous relevant Swift Playgrounds on iPad Primer Tutorial is shown below.

Swift Playgrounds on iPad Primer Tutorial

Swift Playgrounds on iPad Primer Tutorial

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 (in other words, the iOS operating system is a missing part of the equation here). That has led us to assume more than we know, though looking into this topic via our Google search of …


ide for ipad

… had us first looking into Python via “pythonista”, but the $14.99 price tag was far too much for us to absorb so early in the morning, and a warning that exclusive “above the fold” reading can have you suffer from (FOMO) “fear of missing out” syndrome. Reading, then, below the fold, soon turned up the Xcode IDE (we have on macOS, here, and appears “above the fold” regarding blurb actions above) programming language of choice, Swift, with its Apple iPad place …


Swift Playgrounds

… as a great resource into programming and “robotics feeling” coding leading to “programming action”! And the presentation may well suit young’uns getting into programming early, if that’s why you are reading this blog posting. As Swift Playgrounds starts out intimating, to “follow a recipe” and perform “steps in order” is likely to lead to the happiest programming and coding experience (to put it mildly … or … just follow orders … initially … to put it more bluntly).

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?!

Or perhaps you are on an iPad and wish to fork out the $14.99 and get into Python, then that would be interesting too, we have no doubt. Either way, see how we R&D‘ed this topic, on an iPad, with today’s PDF presentation (dare we say) following orders.

We’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, with Apple, on that.

If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in eLearning, Event-Driven Programming, Operating System, Software, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *