Skip to content

Commit

Permalink
Merge pull request #15 from dmiedema/Swift2.0
Browse files Browse the repository at this point in the history
Update for Swift 2.0
  • Loading branch information
tehprofessor committed Jul 28, 2015
2 parents 55f26c0 + 8d7462d commit 7da4bb0
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 69 deletions.
10 changes: 7 additions & 3 deletions MapPointMapper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@
547424DC1A1C1CE800A8478C /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = dmiedema;
TargetAttributes = {
547424E31A1C1CE800A8478C = {
Expand Down Expand Up @@ -316,6 +317,7 @@
COPY_PHASE_STRIP = NO;
EMBEDDED_CONTENT_CONTAINS_SWIFT = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
Expand Down Expand Up @@ -404,6 +406,7 @@
INFOPLIST_FILE = MapPointMapper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
PRODUCT_BUNDLE_IDENTIFIER = "dmiedema.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
RUN_CLANG_STATIC_ANALYZER = YES;
Expand Down Expand Up @@ -440,6 +443,7 @@
INFOPLIST_FILE = MapPointMapper/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
PRODUCT_BUNDLE_IDENTIFIER = "dmiedema.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
RUN_CLANG_STATIC_ANALYZER = YES;
Expand All @@ -454,14 +458,14 @@
FRAMEWORK_SEARCH_PATHS = (
"$(DEVELOPER_FRAMEWORKS_DIR)",
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = MapPointMapperTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "dmiedema.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MapPointMapper.app/Contents/MacOS/MapPointMapper";
};
Expand All @@ -475,10 +479,10 @@
FRAMEWORK_SEARCH_PATHS = (
"$(DEVELOPER_FRAMEWORKS_DIR)",
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
INFOPLIST_FILE = MapPointMapperTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "dmiedema.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MapPointMapper.app/Contents/MacOS/MapPointMapper";
};
Expand Down
2 changes: 1 addition & 1 deletion MapPointMapper/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>dmiedema.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
Expand Down
84 changes: 47 additions & 37 deletions MapPointMapper/Parser/Parser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import MapKit
extension NSString {
/**
Convenience so `isEmpty` can be performed on an `NSString` instance just as if it were a `String`

- returns: `true` if the string is empty, `false` if not
*/
var isEmpty: Bool {
get { return self.length == 0 || self.isEqualToString("") }
Expand All @@ -21,7 +23,7 @@ extension String {
/**
Strip all leading and trailing whitespace from a given `String` instance.

:returns: a newly stripped string instance.
- returns: a newly stripped string instance.
*/
func stringByStrippingLeadingAndTrailingWhiteSpace() -> String {
let mutable = self.mutableCopy() as! NSMutableString
Expand All @@ -35,12 +37,12 @@ class Parser {
/**
Parse a given string of Lat/Lng values to return a collection of `CLLocationCoordinate2D` arrays.

:note: The preferred way/format of the input string is `Well-Known Text` as the parser supports that for multipolygons and such
- note: The preferred way/format of the input string is `Well-Known Text` as the parser supports that for multipolygons and such

:param: input String to parse
:param: longitudeFirst Only used if it is determined to not be `Well-Known Text` format.
- parameter input: String to parse
- parameter longitudeFirst: Only used if it is determined to not be `Well-Known Text` format.

:returns: An array of `CLLocationCoordinate2D` arrays representing the parsed areas/lines
- returns: An array of `CLLocationCoordinate2D` arrays representing the parsed areas/lines
*/
class func parseString(input: NSString, longitudeFirst: Bool) -> [[CLLocationCoordinate2D]] {
return Parser(longitudeFirst: longitudeFirst).parseInput(input)
Expand All @@ -60,23 +62,23 @@ class Parser {
/**
Parse input string into a collection of `CLLocationCoordinate2D` arrays that can be drawn on a map

:note: This method supports (and really works best with/prefers) `Well-Known Text` format
- note: This method supports (and really works best with/prefers) `Well-Known Text` format

:param: input `NSString` to parse
- parameter input: `NSString` to parse

:returns: Collection of `CLLocationCoordinate2D` arrays
- returns: Collection of `CLLocationCoordinate2D` arrays
*/
internal func parseInput(input: NSString) -> [[CLLocationCoordinate2D]] {
var array = [[NSString]]()

let line = input as! String
let line = input as String

if isProbablyGeoString(line) {
self.longitudeFirst = true
var items = [NSString]()

if isMultiItem(line) {
items = stripExtraneousCharacters(line).componentsSeparatedByString("),") as! [NSString]
items = stripExtraneousCharacters(line).componentsSeparatedByString("),")
} else {
items = [stripExtraneousCharacters(line)]
}
Expand All @@ -92,18 +94,19 @@ class Parser {
/**
Convert an array of strings into tuple pairs.

:note: the number of values passed in should probably be even, since it creates pairs.
- note: the number of values passed in should probably be even, since it creates pairs.

:param: array of `[NSString]` array to create tuples from
- parameter array: of `[NSString]` array to create tuples from

:returns: array of collections of tuple pairs where the tuples are lat/lng values as `NSString`s
- returns: array of collections of tuple pairs where the tuples are lat/lng values as `NSString`s
*/
internal func convertStringArraysToTuples(array: [[NSString]]) -> [[(NSString, NSString)]] {
var tmpResults = [(NSString, NSString)]()
var results = [[(NSString, NSString)]]()
for arr in array {
for var i = 0; i < arr.count - 1; i += 2 {
tmpResults.append((arr[i], arr[i + 1]))
let elem = (arr[i], arr[i + 1])
tmpResults.append(elem)
}

if tmpResults.count == 1 {
Expand All @@ -117,13 +120,13 @@ class Parser {
}

/**
:abstract: Naively format a `Well-Known Text` string into array of string values, where each string is a single value
_abstract_: Naively format a `Well-Known Text` string into array of string values, where each string is a single value

:discussion: This removes any lingering parens from the given string, breaks on `,` then breaks on ` ` while filtering out any empty strings.
_discussion_: This removes any lingering parens from the given string, breaks on `,` then breaks on ` ` while filtering out any empty strings.

:param: input String to format, assumed `Well-Known Text` format
- parameter input: String to format, assumed `Well-Known Text` format

:returns: array of strings where each string is one value from the string with all empty strings filtered out.
- returns: array of strings where each string is one value from the string with all empty strings filtered out.
*/
internal func formatStandardGeoDataString(input: NSString) -> [NSString] {
// Remove Extra ()
Expand All @@ -150,18 +153,18 @@ class Parser {

private func splitLine(input: NSString, delimiter: NSString) -> (NSString, NSString) {
let array = input.componentsSeparatedByString(delimiter as String)
return (array.first! as! NSString, array.last! as! NSString)
return (array.first! as NSString, array.last! as NSString)
}

/**
:abstract: Convert a given array of `(String, String)` tuples to array of `CLLocationCoordinate2D` values

:discussion: This attempts to parse the string's double values but does no safety checks if they can be parsed as `double`s.

:param: pairs array of `String` tuples to parse as `Double`s
:param: longitudeFirst boolean flag if the first item in the tuple should be the longitude value
- parameter pairs: array of `String` tuples to parse as `Double`s
- parameter longitudeFirst: boolean flag if the first item in the tuple should be the longitude value

:returns: array of `CLLocationCoordinate2D` values
- returns: array of `CLLocationCoordinate2D` values
*/
internal func convertToCoordinates(pairs: [(NSString, NSString)], longitudeFirst: Bool) -> [CLLocationCoordinate2D] {
var coordinates = [CLLocationCoordinate2D]()
Expand All @@ -184,18 +187,25 @@ class Parser {
Removes any text before lat long points as well as two outer sets of parens.

Example:
```
input => "POLYGON(( 15 32 ))"
output => "15 32"

input => "MULTIPOLYGON((( 15 32 )))"
output => "( 15 32 )"
```

- parameter input: NSString to strip extraneous characters from

:param: input NSString to strip extraneous characters from

:returns: stripped string instance
- returns: stripped string instance
*/
internal func stripExtraneousCharacters(input: NSString) -> NSString {
let regex = NSRegularExpression(pattern: "\\w+\\s*\\((.*)\\)", options: .CaseInsensitive, error: nil)
let regex: NSRegularExpression?
do {
regex = try NSRegularExpression(pattern: "\\w+\\s*\\((.*)\\)", options: .CaseInsensitive)
} catch _ {
regex = nil
}
let match: AnyObject? = regex?.matchesInString(input as String, options: .ReportCompletion, range: NSMakeRange(0, input.length)).first
let range = match?.rangeAtIndex(1)

Expand All @@ -206,17 +216,17 @@ class Parser {
}

/**
:abstract: Attempt to determine if a given string is in `Well-Known Text` format (GeoString as its referred to internally)
_abstract_: Attempt to determine if a given string is in `Well-Known Text` format (GeoString as its referred to internally)

:discussion: This strips any leading & trailing white space before checking for the existance of word characters at the start of the string.
_discussion_: This strips any leading & trailing white space before checking for the existance of word characters at the start of the string.

:param: input String to attempt determine if is in `Well-Known Text` format
- parameter input: String to attempt determine if is in `Well-Known Text` format

:returns: `true` if it thinks it is, `false` otherwise
- returns: `true` if it thinks it is, `false` otherwise
*/
internal func isProbablyGeoString(input: String) -> Bool {
let stripped = input.stringByStrippingLeadingAndTrailingWhiteSpace()
if let geoString = stripped.rangeOfString("^\\w+", options: .RegularExpressionSearch) {
if stripped.rangeOfString("^\\w+", options: .RegularExpressionSearch) != nil {
return true
}
return false
Expand All @@ -225,12 +235,12 @@ class Parser {
/**
Determine if a given string is a `MULTI*` item.

:param: input String to check
- parameter input: String to check

:returns: `true` if the string starts with `MULTI`. `false` otherwise
- returns: `true` if the string starts with `MULTI`. `false` otherwise
*/
internal func isMultiItem(input: String) -> Bool {
if let isPolygon = input.rangeOfString("MULTI", options: .RegularExpressionSearch) {
if input.rangeOfString("MULTI", options: .RegularExpressionSearch) != nil {
return true
}
return false
Expand All @@ -239,11 +249,11 @@ class Parser {
/**
Determines if a the collection is space delimited or not

:note: This function should only be passed a single entry or else it will probably have incorrect results
- note: This function should only be passed a single entry or else it will probably have incorrect results

:param: input a single entry from the collection as a string
- parameter input: a single entry from the collection as a string

:returns: `true` if elements are space delimited, `false` otherwise
- returns: `true` if elements are space delimited, `false` otherwise
*/
private func isSpaceDelimited(input: String) -> Bool {
let array = input.componentsSeparatedByString(" ")
Expand Down
46 changes: 21 additions & 25 deletions MapPointMapper/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,20 @@ class ViewController: NSViewController, MKMapViewDelegate, NSTextFieldDelegate {
}

@IBAction func centerAllLinesPressed(sender: NSButton) {
let polylines = mapview.overlays as! [MKOverlay]
let polylines = mapview.overlays as [MKOverlay]
let boundingMapRect = boundingMapRectForPolylines(polylines)
mapview.setVisibleMapRect(boundingMapRect, edgePadding: NSEdgeInsets(top: 10, left: 10, bottom: 10, right: 10), animated: true)
}

// MARK: MKMapDelegate
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.alpha = 1.0
renderer.lineWidth = 4.0
renderer.strokeColor = colorWell.color
return renderer
}

// MARK: NSTextFieldDelegate
override func keyUp(theEvent: NSEvent) {
if theEvent.keyCode == 36 { // 36 is the return key apparently
Expand All @@ -116,9 +117,9 @@ class ViewController: NSViewController, MKMapViewDelegate, NSTextFieldDelegate {
/**
Create an `MKOverlay` for a given array of `CLLocationCoordinate2D` instances

:param: mapPoints array of `CLLocationCoordinate2D` instances to convert
- parameter mapPoints: array of `CLLocationCoordinate2D` instances to convert

:returns: an MKOverlay created from array of `CLLocationCoordinate2D` instances
- returns: an MKOverlay created from array of `CLLocationCoordinate2D` instances
*/
private func createPolylineForCoordinates(mapPoints: [CLLocationCoordinate2D]) -> MKOverlay {
let coordinates = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(mapPoints.count)
Expand All @@ -139,11 +140,11 @@ class ViewController: NSViewController, MKMapViewDelegate, NSTextFieldDelegate {
/**
Get the bounding `MKMapRect` that contains all given `MKOverlay` objects

:warning: If no `MKOverlay` objects are included the resulting `MKMapRect` will be nonsensical and will results in a warning.
- warning: If no `MKOverlay` objects are included the resulting `MKMapRect` will be nonsensical and will results in a warning.

:param: polylines array of `MKOverlay` objects.
- parameter polylines: array of `MKOverlay` objects.

:returns: an `MKMapRect` that contains all the given `MKOverlay` objects
- returns: an `MKMapRect` that contains all the given `MKOverlay` objects
*/
private func boundingMapRectForPolylines(polylines: [MKOverlay]) -> MKMapRect {
var minX = Double.infinity
Expand Down Expand Up @@ -171,25 +172,20 @@ class ViewController: NSViewController, MKMapViewDelegate, NSTextFieldDelegate {
/**
Read a given file at a url

:param: passedURL `NSURL` to attempt to read
- parameter passedURL: `NSURL` to attempt to read
*/
private func readFileAtURL(passedURL: NSURL?) {
if let url = passedURL {
if !NSFileManager.defaultManager().isReadableFileAtPath(url.absoluteString!) {
NSAlert(error: NSError(domain: "com.dmiedema.MapPointMapper", code: -42, userInfo: [NSLocalizedDescriptionKey: "File is unreadable at \(url.absoluteString)"]))
}

var error: NSError?
let contents = NSString(contentsOfURL: url, encoding: NSUTF8StringEncoding, error: &error)

if let err = error {
NSAlert(error: err)
return
}

if let content = contents {
renderInput(content)
}
guard let url = passedURL else { return }

if !NSFileManager.defaultManager().isReadableFileAtPath(url.absoluteString) {
NSAlert(error: NSError(domain: "com.dmiedema.MapPointMapper", code: -42, userInfo: [NSLocalizedDescriptionKey: "File is unreadable at \(url.absoluteString)"])).runModal()
}

do {
let contents = try NSString(contentsOfURL: url, encoding: NSUTF8StringEncoding) as String
renderInput(contents)
} catch {
NSAlert(error: error as NSError).runModal()
}
} // end readFileAtURL

Expand All @@ -205,7 +201,7 @@ class ViewController: NSViewController, MKMapViewDelegate, NSTextFieldDelegate {
/**
Parse the given input.

:param: input `NSString` to parse and draw on the map. If no string is given this is essentially a noop
- parameter input: `NSString` to parse and draw on the map. If no string is given this is essentially a noop
*/
private func parseInput(input: NSString) {

Expand Down
2 changes: 1 addition & 1 deletion MapPointMapperTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>dmiedema.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
Expand Down
Loading

0 comments on commit 7da4bb0

Please sign in to comment.