Created
June 7, 2015 11:09
-
-
Save delebedev/6a2b11a5f3514a77da51 to your computer and use it in GitHub Desktop.
Export Foursquare checkins to GPX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.swift | |
// ForsquareGPX | |
// | |
// Created by Dzianis Lebedzeu on 07/06/2015. | |
// Copyright (c) 2015 Home. All rights reserved. | |
// | |
import Foundation | |
let token = "YOUR_FORSQUARE_TOKEN" | |
var checkins = [NSDictionary]() | |
let limit = 250 | |
func iso8601Formatter() -> NSDateFormatter { | |
let formatter = NSDateFormatter() | |
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") | |
formatter.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'" | |
return formatter | |
} | |
func escapeXML(xml: String) -> String { | |
return CFXMLCreateStringByEscapingEntities(kCFAllocatorDefault, xml, nil) as String | |
} | |
func checkinsURLWithOffset(offset: Int) -> NSURL { | |
let path = "https://api.foursquare.com/v2/users/self/checkins" | |
let urlComponents = NSURLComponents(string: path)! | |
let dateFormatter = NSDateFormatter() | |
dateFormatter.dateFormat = "YYYYMMDD" | |
urlComponents.queryItems = [ | |
NSURLQueryItem(name: "oauth_token", value: token), | |
NSURLQueryItem(name: "v", value: dateFormatter.stringFromDate(NSDate())), | |
NSURLQueryItem(name: "limit", value: "\(limit)"), | |
NSURLQueryItem(name: "offset", value: "\(offset)")] | |
return urlComponents.URL! | |
} | |
func fetchCheckins(offset: Int) { | |
println("fetching checkins with offset: \(offset)") | |
let task = NSURLSession.sharedSession().dataTaskWithURL(checkinsURLWithOffset(offset)) { (data, urlResponse, error) -> Void in | |
if let error = error { | |
println(error.localizedDescription) | |
exit(1) | |
} | |
var jsonError: NSError? | |
let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &jsonError) as? NSDictionary | |
if let json = json { | |
if let serverError = json.valueForKeyPath("meta.errorDetail") as? String { | |
println(serverError) | |
return | |
} | |
let items = json.valueForKeyPath("response.checkins.items") as? [NSDictionary] | |
let count = json.valueForKeyPath("response.checkins.count") as? Int | |
if let items = items, count = count { | |
if (offset < count) { | |
checkins += items | |
fetchCheckins(offset + limit) | |
} else { | |
writeCheckinsToGPX(checkins) | |
} | |
} | |
} else if let jsonError = jsonError { | |
println(jsonError.localizedDescription) | |
exit(1) | |
} | |
} | |
task.resume() | |
} | |
func writeCheckinsToGPX(checkins: [NSDictionary]) { | |
let formatter = iso8601Formatter() | |
let now = formatter.stringFromDate(NSDate()) | |
var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" + | |
"<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\" xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v1\" creator=\"Oregon 400t\" version=\"1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd\">\n" + | |
"<metadata>" + | |
"<link href=\"http://www.foursquare.com\">" + | |
"<text>Foursquare Checkins</text>" + | |
"</link>" + | |
"<time>\(now)</time>" + | |
"</metadata>" + "\n" | |
for checkin in checkins { | |
if let name = checkin.valueForKeyPath("venue.name") as? String, | |
let lat = checkin.valueForKeyPath("venue.location.lat") as? Double, | |
let lon = checkin.valueForKeyPath("venue.location.lng") as? Double, | |
let time = checkin.valueForKeyPath("createdAt") as? Double { | |
let date = NSDate(timeIntervalSince1970: time) | |
xml += "\n<trk><name>\(escapeXML(name))</name><trkseg><trkpt lat=\"\(lat)\" lon=\"\(lon)\"><time>\(formatter.stringFromDate(date))</time></trkpt></trkseg></trk>" | |
} | |
} | |
xml += "\n" | |
xml += "</gpx>" | |
println("writing data to GPX file...") | |
var error: NSError? | |
xml.writeToFile("foursquare.gpx", atomically: true, encoding: NSUTF8StringEncoding, error: &error) | |
assert( error == nil, "Failed to write GPX.") | |
println("Done.") | |
exit(0) | |
} | |
fetchCheckins(0) | |
dispatch_main() // TODO: Any better solutions for async console execution? | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment