Skip to content

Instantly share code, notes, and snippets.

@rodericj
Last active May 27, 2016 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodericj/0bf0b70dc8a7faf0cce5a5c52b60d917 to your computer and use it in GitHub Desktop.
Save rodericj/0bf0b70dc8a7faf0cce5a5c52b60d917 to your computer and use it in GitHub Desktop.
//: Playground - Track the ISS from a playground
import MapKit
import XCPlayground
class ISSFetcher: NSObject {
var completion: (Double, Double) -> Void
var timer: NSTimer?
init(inCompletion: (Double, Double) -> Void) {
completion = inCompletion
}
func getNext() {
guard let url = NSURL(string: "http://api.open-notify.org/iss-now.json") else {
print("we need a url")
return
}
let request = NSURLRequest(URL: url)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) in
if let data = data, json = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as? [String: AnyObject],
position = json?["iss_position"],
latitude = position["latitude"],
longitude = position["longitude"] {
self.completion(latitude as! Double, longitude as! Double)
}
if let error = error {
print("error fetching new coordinates", error)
}
})
task.resume()
}
func stop() {
timer?.invalidate()
}
func start() {
// kick things off
getNext()
// set it up so we do it again after 5 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(getNext), userInfo: nil, repeats: true)
}
}
class ISSAnnotation: NSObject, MKAnnotation {
dynamic var coordinate: CLLocationCoordinate2D
var title: String? = "ISS"
init(lat: Double, lon: Double) {
coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
}
func update(newLatitude: Double, newLongitude: Double) {
coordinate = CLLocationCoordinate2D(latitude: newLatitude, longitude: newLongitude)
}
}
// This is our main()
let frame = CGRect(x: 0, y: 0, width: 400, height: 400 )
let mapView = MKMapView(frame: frame )
mapView.mapType = .Satellite
let annotation = ISSAnnotation(lat: 0,lon: 0)
mapView.addAnnotation(annotation)
// Create the fetcher object with completion block
let fetcher = ISSFetcher(inCompletion: {(lat, lon) in
dispatch_async(dispatch_get_main_queue(), {
UIView.animateWithDuration(3, animations: {
print("new coordinates", lat, lon)
annotation.update(lat, newLongitude: lon)
mapView.centerCoordinate = annotation.coordinate
})
})
})
// start the fetcher
fetcher.start()
// view the map in the timeline!
XCPlaygroundPage.currentPage.liveView = mapView
@adamstener
Copy link

adamstener commented May 27, 2016

This one is purely preference, but I like the look of this trailing closure syntax better (I think this is what pzearfoss was referring to, though there are many variations of syntax closure syntax). There are many many people who will say they like other ways better, because there are lots of ways of writing closure syntax, but the trailing ')' at the end of a method is just less appealing to me. The argument that most people have is that your current syntax looks more like a closure, so its' more obvious what is going on, I just think this way is cleaner, and I've gotten used to it. There is no performance benefit, strictly which syntax works better for whatever team/person is working on the code:

// Create the fetcher object with completion block
let fetcher = ISSFetcher() { lat, lon in
    dispatch_async(dispatch_get_main_queue()) {
        UIView.animateWithDuration(3) {
            print("new coordinates", lat, lon)
            annotation.update(lat, newLongitude: lon)
            mapView.centerCoordinate = annotation.coordinate
        }
    }
}




let task = session.dataTaskWithRequest(request) { data, response, error in
            if let data = data, json = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as? [String: AnyObject],
                position = json?["iss_position"],
                latitude = position["latitude"],
                longitude = position["longitude"] {
                self.completion(latitude as! Double, longitude as! Double)
            }
            if let error = error {
                print("error fetching new coordinates", error)
            }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment