diff --git a/.travis.yml b/.travis.yml index d615e1b..828431b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: objective-c -osx_image: xcode7.1 +osx_image: xcode8 before_script: - export LANG=en_US.UTF-8 script: - - xctool -project Polyline.xcodeproj -scheme Polyline -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO - - xctool test -project Polyline.xcodeproj -scheme Polyline -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO + - xcodebuild -project Polyline.xcodeproj -scheme Polyline -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO + - xcodebuild test -project Polyline.xcodeproj -scheme Polyline -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.0' ONLY_ACTIVE_ARCH=NO diff --git a/Polyline.xcodeproj/project.pbxproj b/Polyline.xcodeproj/project.pbxproj index b1d9ad7..0331f04 100644 --- a/Polyline.xcodeproj/project.pbxproj +++ b/Polyline.xcodeproj/project.pbxproj @@ -659,7 +659,7 @@ SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -679,17 +679,13 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; 207F641519B5DF7E005261FA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -698,22 +694,18 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.ramoapps.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; 207F641619B5DF7E005261FA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); INFOPLIST_FILE = PolylineTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.ramoapps.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -737,7 +729,7 @@ PRODUCT_NAME = Polyline; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -762,7 +754,7 @@ PRODUCT_NAME = Polyline; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -779,7 +771,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests; PRODUCT_NAME = PolylineTests; SDKROOT = macosx; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -797,7 +789,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests; PRODUCT_NAME = PolylineTests; SDKROOT = macosx; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -819,6 +811,7 @@ PRODUCT_NAME = Polyline; SDKROOT = appletvos; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -843,6 +836,7 @@ PRODUCT_NAME = Polyline; SDKROOT = appletvos; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -859,6 +853,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests; PRODUCT_NAME = PolylineTests; SDKROOT = appletvos; + SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Debug; @@ -875,6 +870,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests; PRODUCT_NAME = PolylineTests; SDKROOT = appletvos; + SWIFT_VERSION = 3.0; TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Release; @@ -898,7 +894,7 @@ PRODUCT_NAME = Polyline; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; @@ -924,7 +920,7 @@ PRODUCT_NAME = Polyline; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; diff --git a/Polyline/Polyline.swift b/Polyline/Polyline.swift index bcd2cfe..f5af4a5 100644 --- a/Polyline/Polyline.swift +++ b/Polyline/Polyline.swift @@ -106,7 +106,7 @@ public struct Polyline { /// - parameter precision: The precision used to encode coordinates (default: `1e5`) /// /// - returns: A `String` representing the encoded Polyline -public func encodeCoordinates(coordinates: [CLLocationCoordinate2D], precision: Double = 1e5) -> String { +public func encodeCoordinates(_ coordinates: [CLLocationCoordinate2D], precision: Double = 1e5) -> String { var previousCoordinate = IntegerCoordinates(0, 0) var encodedPolyline = "" @@ -131,7 +131,7 @@ public func encodeCoordinates(coordinates: [CLLocationCoordinate2D], precision: /// - parameter precision: The precision used to encode locations (default: `1e5`) /// /// - returns: A `String` representing the encoded Polyline -public func encodeLocations(locations: [CLLocation], precision: Double = 1e5) -> String { +public func encodeLocations(_ locations: [CLLocation], precision: Double = 1e5) -> String { return encodeCoordinates(toCoordinates(locations), precision: precision) } @@ -141,7 +141,7 @@ public func encodeLocations(locations: [CLLocation], precision: Double = 1e5) -> /// - parameter levels: The `Array` of `UInt32` levels that you want to encode /// /// - returns: A `String` representing the encoded Levels -public func encodeLevels(levels: [UInt32]) -> String { +public func encodeLevels(_ levels: [UInt32]) -> String { return levels.reduce("") { $0 + encodeLevel($1) } @@ -153,12 +153,12 @@ public func encodeLevels(levels: [UInt32]) -> String { /// - parameter precision: The precision used to decode coordinates (default: `1e5`) /// /// - returns: A `[CLLocationCoordinate2D]` representing the decoded polyline if valid, `nil` otherwise -public func decodePolyline(encodedPolyline: String, precision: Double = 1e5) -> [CLLocationCoordinate2D]? { +public func decodePolyline(_ encodedPolyline: String, precision: Double = 1e5) -> [CLLocationCoordinate2D]? { - let data = encodedPolyline.dataUsingEncoding(NSUTF8StringEncoding)! + let data = encodedPolyline.data(using: String.Encoding.utf8)! - let byteArray = unsafeBitCast(data.bytes, UnsafePointer.self) - let length = Int(data.length) + let byteArray = unsafeBitCast((data as NSData).bytes, to: UnsafePointer.self) + let length = Int(data.count) var position = Int(0) var decodedCoordinates = [CLLocationCoordinate2D]() @@ -190,7 +190,7 @@ public func decodePolyline(encodedPolyline: String, precision: Double = 1e5) -> /// - parameter precision: The precision used to decode locations (default: 1e5) /// /// - returns: A [CLLocation] representing the decoded polyline if valid, nil otherwise -public func decodePolyline(encodedPolyline: String, precision: Double = 1e5) -> [CLLocation]? { +public func decodePolyline(_ encodedPolyline: String, precision: Double = 1e5) -> [CLLocation]? { return decodePolyline(encodedPolyline, precision: precision).map(toLocations) } @@ -200,7 +200,7 @@ public func decodePolyline(encodedPolyline: String, precision: Double = 1e5) -> /// - parameter encodedLevels: The `String` representing the levels to decode /// /// - returns: A `[UInt32]` representing the decoded Levels if the `String` is valid, `nil` otherwise -public func decodeLevels(encodedLevels: String) -> [UInt32]? { +public func decodeLevels(_ encodedLevels: String) -> [UInt32]? { var remainingLevels = encodedLevels.unicodeScalars var decodedLevels = [UInt32]() @@ -223,7 +223,7 @@ public func decodeLevels(encodedLevels: String) -> [UInt32]? { // MARK: Encode Coordinate -private func encodeCoordinate(locationCoordinate: IntegerCoordinates) -> String { +private func encodeCoordinate(_ locationCoordinate: IntegerCoordinates) -> String { let latitudeString = encodeSingleComponent(locationCoordinate.latitude) let longitudeString = encodeSingleComponent(locationCoordinate.longitude) @@ -231,7 +231,7 @@ private func encodeCoordinate(locationCoordinate: IntegerCoordinates) -> String return latitudeString + longitudeString } -private func encodeSingleComponent(value: Int) -> String { +private func encodeSingleComponent(_ value: Int) -> String { var intValue = value @@ -247,15 +247,15 @@ private func encodeSingleComponent(value: Int) -> String { // MARK: Encode Levels -private func encodeLevel(level: UInt32) -> String { +private func encodeLevel(_ level: UInt32) -> String { return encodeFiveBitComponents(Int(level)) } -private func encodeFiveBitComponents(value: Int) -> String { +private func encodeFiveBitComponents(_ value: Int) -> String { var remainingComponents = value var fiveBitComponent = 0 - var returnString = "" + var returnString = String() repeat { fiveBitComponent = remainingComponents & 0x1F @@ -265,8 +265,9 @@ private func encodeFiveBitComponents(value: Int) -> String { } fiveBitComponent += 63 - - returnString.append(UnicodeScalar(fiveBitComponent)) + + let char = UnicodeScalar(fiveBitComponent)! + returnString.append(String(char)) remainingComponents = remainingComponents >> 5 } while (remainingComponents != 0) @@ -277,9 +278,9 @@ private func encodeFiveBitComponents(value: Int) -> String { // We use a byte array (UnsafePointer) here for performance reasons. Check with swift 2 if we can // go back to using [Int8] -private func decodeSingleCoordinate(byteArray byteArray: UnsafePointer, length: Int, inout position: Int, precision: Double = 1e5) throws -> Double { +private func decodeSingleCoordinate(byteArray: UnsafePointer, length: Int, position: inout Int, precision: Double = 1e5) throws -> Double { - guard position < length else { throw PolylineError.SingleCoordinateDecodingError } + guard position < length else { throw PolylineError.singleCoordinateDecodingError } let bitMask = Int8(0x1F) @@ -298,7 +299,7 @@ private func decodeSingleCoordinate(byteArray byteArray: UnsafePointer, le } while ((currentChar & 0x20) == 0x20) && (position < length) && (componentCounter < 6) if (componentCounter == 6) && ((currentChar & 0x20) == 0x20) { - throw PolylineError.SingleCoordinateDecodingError + throw PolylineError.singleCoordinateDecodingError } if (coordinate & 0x01) == 0x01 { @@ -312,31 +313,31 @@ private func decodeSingleCoordinate(byteArray byteArray: UnsafePointer, le // MARK: Decode Levels -private func extractNextChunk(inout encodedString: String.UnicodeScalarView) throws -> String { +private func extractNextChunk(_ encodedString: inout String.UnicodeScalarView) throws -> String { var currentIndex = encodedString.startIndex while currentIndex != encodedString.endIndex { let currentCharacterValue = Int32(encodedString[currentIndex].value) if isSeparator(currentCharacterValue) { let extractedScalars = encodedString[encodedString.startIndex...currentIndex] - encodedString = encodedString[currentIndex.successor().. UInt32 { +private func decodeLevel(_ encodedLevel: String) -> UInt32 { let scalarArray = [] + encodedLevel.unicodeScalars return UInt32(agregateScalarArray(scalarArray)) } -private func agregateScalarArray(scalars: [UnicodeScalar]) -> Int32 { +private func agregateScalarArray(_ scalars: [UnicodeScalar]) -> Int32 { let lastValue = Int32(scalars.last!.value) let fiveBitComponents: [Int32] = scalars.map { scalar in @@ -348,27 +349,27 @@ private func agregateScalarArray(scalars: [UnicodeScalar]) -> Int32 { } } - return Array(fiveBitComponents.reverse()).reduce(0) { ($0 << 5 ) | $1 } + return Array(fiveBitComponents.reversed()).reduce(0) { ($0 << 5 ) | $1 } } // MARK: Utilities -enum PolylineError: ErrorType { - case SingleCoordinateDecodingError - case ChunkExtractingError +enum PolylineError: Error { + case singleCoordinateDecodingError + case chunkExtractingError } -private func toCoordinates(locations: [CLLocation]) -> [CLLocationCoordinate2D] { +private func toCoordinates(_ locations: [CLLocation]) -> [CLLocationCoordinate2D] { return locations.map {location in location.coordinate} } -private func toLocations(coordinates: [CLLocationCoordinate2D]) -> [CLLocation] { +private func toLocations(_ coordinates: [CLLocationCoordinate2D]) -> [CLLocation] { return coordinates.map { coordinate in CLLocation(latitude:coordinate.latitude, longitude:coordinate.longitude) } } -private func isSeparator(value: Int32) -> Bool { +private func isSeparator(_ value: Int32) -> Bool { return (value - 63) & 0x20 != 0x20 } diff --git a/PolylineTests/FunctionalPolylineTests.swift b/PolylineTests/FunctionalPolylineTests.swift index f79072c..45913a2 100644 --- a/PolylineTests/FunctionalPolylineTests.swift +++ b/PolylineTests/FunctionalPolylineTests.swift @@ -178,4 +178,4 @@ class FunctionalPolylineTests : XCTestCase { XCTAssertEqual(encodeLocations(locations), "AA@@") } -} \ No newline at end of file +} diff --git a/PolylineTests/PolylineTests.swift b/PolylineTests/PolylineTests.swift index b18b117..9d14eb5 100644 --- a/PolylineTests/PolylineTests.swift +++ b/PolylineTests/PolylineTests.swift @@ -288,7 +288,7 @@ class PolylineTests:XCTestCase { // Github Issue 8 func testPerformances() { - self.measureBlock { + self.measure { let _ = Polyline(encodedPolyline:"wamrIo{gnAnG_CVIm@{NEsDFgAHu@^{C`@sC@_As@eWEoBIw@?QDYd@oB@Uv@eDHOViAPwB@_ACUGQIcDYiIsA{a@EcB?iBD]JyBV}C@GJKDOCUMOO@MLy@@}ATI@McEQsLCcC?}@De@BQNe@gDcEgBsCSa@Yy@QiAS{D?gAJ_APmAt@wD`@eDDq@?aCk@uTcBif@KiBSkBa@wBUu@u@yB}CmHo@oAw@kA_@g@y@s@w@i@eJiF}BcB_BwAoCsDaB_DwLsWaBaDyB}Dm@qA_AcDEOIq@Sy@AuBBu@LgAR}@|@kCt@}Ab@s@^g@hAoAb@]jBkAdHqDt@[~@QxABNEHEdA}@TYbAyATQXKdC[n@Sr@c@r@}@|BwE~@eBjAyAvAaAlCaBlCoAjC_A|Cu@lLeBnDcAxBy@xDmBlEkCvDcCrFaEHGxAg@nAYf@Cz@@hCd@zAHj@MTIf@c@T]Zo@b@iBFo@DgA?k@CgAEa@Y_BoBeHo@sC{@iFg@qBk@aDqBeJaBcG}E_P{AsFq@kCk@eCwAmIm@yEk@cFg@eHU{FAiBMaIIiHImDSwF_@gGc@wFq@_G]aCc@yCcAsFiAeFCQ}FgUcEaRmBsJ_C}M_BaK{A{KsC_V_Gil@WqDy@kJk@eHyAeSu@mL]{Ha@kNI_GEkKFcV?mHKeHK}Cg@eKa@cFWmCm@}Ea@uCcCqMm@mCmAoEq@wBuA{DuAmD_BiDeDkG]u@{AwC{BaFiA_Dy@gCiA_Em@cCeAyEo@oDs@yEq@wFm@iHIyA]qIQiJIiBAkBDg@Ru@DOJSFc@Bc@AUIg@M[]aDIsAWyUs@cx@MqJ[wL_@gLg@uLo@oLiAkRo@_Iy@kH_@uCy@}Ey@mDaBcGkDsIgBkDgAaBiDiEkBqB}AkAmCaBaImDkAs@{BeBaBkBmBqCaCoEy@sBw@}Bq@aCoA{EeA_Fg@qCsAaJ_@sC]}CUqC_@qFIuAUkGQeIG}QCsRFuD?_CDgIAoJMyMUaLq@mO[wF}@uMe@oFc@kDu@wF{@{E_BwH[wAmDkL{HaToC}HwA{DiAkD_AuDyA_Ig@}Dg@wCyCiTi@cDy@qGcAeGkHyi@oAcJwBoPwAyJs@yFy@kFoFy_@wBeNkA}HcEuZeBqKOyAs@kEk@qEq@qE[cBWkBoAmHsBeOCQCuD\\{Bd@_Cz@aAbDuC~HuH|BsCjBqCdAgBrAgC~AwDjA{ClA}DrAmFf@_Cz@yE^aCh@_EVaCl@eHPcCp@qNbAuPf@_HtA}Nr@gG|@}GfAmHbB_JrAqG~AoItFkX`@_Cd@uDb@iEb@mFTiEXmJDyDAkDGeD]sIe@oG_A_Ko@gGaA{HwAyJi@eDqAoHiCiMmByH_EmOoCkIaGyR]_A}AcF_AiD}@_DwAiHc@oCa@kDa@gGQaEEwJFoD^}Ib@gF^kCZeCT}@x@oE\\yAtCaOb@iCv@qGV{CXwEJwE\\gh@RaMZsIv@iMX}CXyBnAeIj@qCx@cDrCkJrIeWdAmDp@mC`AsE\\gC~AeJTqBJq@VeDd@yH`@qMZaNx@c\\DaCDiAjAmc@f@iOjDwy@RqC|AcR|@}HtAiK~@oGn@oD|Hoa@vAwJ\\oCl@sGb@cF`@kHF_C`@iKJiH?gJIiDCoBo@yRsBga@[cREsFBeU`@sOTwGFeC~@cWf@wK~@_WbAu[vEmuAfAoXHiLHmTKe]GiCYoHY_Ew@aH}CmSwBkQgBcPw@uKScFCwCHeHZcIx@iOf@cMF}Bn@s^v@k\\n@i[j@aRNwGf@aPNsHb@kP|@yWp@wPLiFLqCbBej@?m@f@sQnAi_@b@mNlAg[VqE\\yELaCLuAdAmKXqB`@{D~BcTn@aGDm@NiATqC@i@F_BCeBOqDK}@e@yCAUDYBQFKn@Er@Bt@Jb@ApBS`CHfFIpEo@lFgB`FwC|@u@vCoCxA}AdEsG`CgFr@kBnAcE`BcHd@uCb@{Dj@kHNsCrAq`@T}ZFSFkAR_BBQDIrBwB|Ca@fGKhADbLfBlD`AhCz@pExBtBpAxCtBt@b@dBr@|@TjBTnBCbAK^IxCeAp@]xC}Bv@u@rCuDxSo\\jBsCfnAgnB|TiZjD}Df@a@bD{BpDsBfIyCvh@yXzB}@pAYnEi@tGArD}@nOsFxJuFjLeIvF}C`GkEtBmA|AUn@AdQP~Fo@zBNtO~B`CV`@@b@I~@o@d@i@|@gB`IeT|C{Ib@aB^iB~DmS`AsD~@eCb@_AXe@lBmCjd@m`@rJcIxKgKbEcDzQmS|CyCfDiCbDmBjBy@tEaBfIqAnQmBbA[|AY|EgBdF_CxH_GtAmAbDsDd@o@|e@mt@vCaEhHqIbL{KvF}DrNmJl@El@c@v@g@\\s@~@o@tG_E\\AbEiCZe@dB}@hGsA^EdCBfC[zNy@`Di@fAM`@Mz@_@~UcIdHcB~CWdACx]nAnFl@pBh@fEvBjRfKrP~IvGlCfB\\rF^n@@~AKpC]fYeH`@EfECrDZ`Ej@xFp@rBFtBErAKnCe@~Ae@lBu@~HcEjF{BpJkDzJaDpCmAtDiC|BqBhEaFbCeCXChBuApBcAb@EJ@RBPEFQh@a@pBq@R@RJL@H?Jd@Xf@TFNATONSDKz@o@XMp@OTMpBUfAQjDoA|BwAv@o@j@]~A_BtIyJtEcGpC_EHKLNNEDKBOC[tDqFtAaBt@u@jAeAfBuALKfA_BjDoEfDiC~@a@BCYyDYsBCQz@aAHIP~@") } }