├── .swift-version
├── Tests
├── LinuxMain.swift
└── PolylineTests
│ ├── Info.plist
│ ├── XCTestManifests.swift
│ ├── FunctionalPolylineTests.swift
│ └── PolylineTests.swift
├── Polyline.xcodeproj
├── xcuserdata
│ ├── rmor.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ ├── Polyline.xcscheme
│ │ │ └── PolylineTests.xcscheme
│ └── raphael.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── raphael.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── Polyline.xccheckout
├── xcshareddata
│ └── xcschemes
│ │ ├── PolylineWatch.xcscheme
│ │ ├── PolylineTV.xcscheme
│ │ ├── PolylineMac.xcscheme
│ │ └── Polyline.xcscheme
└── project.pbxproj
├── .travis
└── build.sh
├── .cocoadocs.yml
├── .gitignore
├── .travis.yml
├── Sources
└── Polyline
│ ├── Info.plist
│ ├── Polyline.h
│ ├── CoreLocation.swift
│ └── Polyline.swift
├── Package.swift
├── LICENSE.txt
├── Polyline.podspec
└── README.md
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.0
2 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import PolylineTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += PolylineTests.__allTests()
7 |
8 | XCTMain(tests)
9 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcuserdata/rmor.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/project.xcworkspace/xcuserdata/raphael.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/raphaelmor/Polyline/HEAD/Polyline.xcodeproj/project.xcworkspace/xcuserdata/raphael.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Polyline.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.travis/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 |
5 | if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
6 | xcodebuild $ACTION -project Polyline.xcodeproj -scheme "$SCHEME" -destination "$DESTINATION" ONLY_ACTIVE_ARCH=NO
7 | swift build
8 | swift test
9 | fi
10 |
11 | if [[ $TRAVIS_OS_NAME == 'linux' ]]; then
12 | eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
13 | swift build
14 | fi
15 |
--------------------------------------------------------------------------------
/.cocoadocs.yml:
--------------------------------------------------------------------------------
1 | highlight-font: '"GT Walsheim", "gt_walsheim_regular", "Avant Garde Gothic ITCW01Dm", "Avant Garde", "Helvetica Neue", "Arial" '
2 | body: '"Helvetica Neue", "Arial", san-serif'
3 | code: '"Monaco", "Menlo", "Consolas", "Courier New", monospace'
4 |
5 | highlight-color: "#008A88"
6 | highlight-dark-color: "#005E5D"
7 | darker-color: "#C6B7B2"
8 | darker-dark-color: "#A8A8A8"
9 | background-color: "#F2F2F2"
10 | alt-link-color: "#004241"
11 | warning-color: "#B80E3D"
12 |
13 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcuserdata/raphael.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SuppressBuildableAutocreation
6 |
7 | 207F63FD19B5DF7E005261FA
8 |
9 | primary
10 |
11 |
12 | 207F640819B5DF7E005261FA
13 |
14 | primary
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | .DS_Store
4 | build/
5 | .build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata
15 | *.xccheckout
16 | *.moved-aside
17 | DerivedData
18 | *.hmap
19 | *.ipa
20 | *.xcuserstate
21 |
22 | # CocoaPods
23 | #
24 | # We recommend against adding the Pods directory to your .gitignore. However
25 | # you should judge for yourself, the pros and cons are mentioned at:
26 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
27 | #
28 | # Pods/
29 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: bash
2 | os:
3 | - linux
4 | - osx
5 | osx_image: xcode12.2
6 | env: SCHEME=
7 | before_script:
8 | - export LANG=en_US.UTF-8
9 | - export SWIFT_VERSION=5.0
10 | script:
11 | - ./.travis/build.sh
12 | jobs:
13 | include:
14 | - os: osx
15 | env: SCHEME=Polyline ACTION=test DESTINATION='platform=iOS Simulator,name=iPhone 11,OS=14.2' ONLY_ACTIVE_ARCH=NO
16 | - os: osx
17 | env: SCHEME=PolylineMac ACTION=test DESTINATION='platform=OS X'
18 | - os: osx
19 | env: SCHEME=PolylineTV ACTION=test DESTINATION='platform=tvOS Simulator,name=Apple TV,OS=14.2'
20 | - os: osx
21 | env: SCHEME=PolylineWatch ACTION=build DESTINATION='platform=watchOS Simulator,name=Apple Watch Series 6 - 44mm,OS=7.1'
22 | exclude:
23 | - os: osx
24 | env: SCHEME=
25 |
--------------------------------------------------------------------------------
/Tests/PolylineTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 5.1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 7
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcuserdata/rmor.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Polyline.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | PolylineTests.xcscheme
13 |
14 | orderHint
15 | 1
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 207F63FD19B5DF7E005261FA
21 |
22 | primary
23 |
24 |
25 | 207F640819B5DF7E005261FA
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Sources/Polyline/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 5.1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 7
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "Polyline",
8 | products: [
9 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
10 | .library(
11 | name: "Polyline",
12 | targets: ["Polyline"]),
13 | ],
14 | dependencies: [
15 | // Dependencies declare other packages that this package depends on.
16 | // .package(url: /* package url */, from: "1.0.0"),
17 | ],
18 | targets: [
19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
21 | .target(
22 | name: "Polyline",
23 | dependencies: []),
24 | .testTarget(
25 | name: "PolylineTests",
26 | dependencies: ["Polyline"]),
27 | ]
28 | )
29 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Raphaël Mor
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/Sources/Polyline/Polyline.h:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | //
3 | // Copyright (c) 2015 Raphaël Mor
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | #import
24 |
25 | // ! Project version number for Polyline.
26 | FOUNDATION_EXPORT double PolylineVersionNumber;
27 |
28 | // ! Project version string for Polyline.
29 | FOUNDATION_EXPORT const unsigned char PolylineVersionString[];
30 |
31 | // In this header, you should import all the public headers of your framework using statements like #import
--------------------------------------------------------------------------------
/Polyline.xcodeproj/project.xcworkspace/xcshareddata/Polyline.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 9077EB1E-81E3-4244-A802-AC91B9350FEB
9 | IDESourceControlProjectName
10 | Polyline
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 49CDAB8249A689DD2FB684F10E837CD2D77E0BE3
14 | https://github.com/raphaelmor/Polyline
15 |
16 | IDESourceControlProjectPath
17 | Polyline.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 49CDAB8249A689DD2FB684F10E837CD2D77E0BE3
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/raphaelmor/Polyline
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | 49CDAB8249A689DD2FB684F10E837CD2D77E0BE3
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 49CDAB8249A689DD2FB684F10E837CD2D77E0BE3
36 | IDESourceControlWCCName
37 | Polyline
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Sources/Polyline/CoreLocation.swift:
--------------------------------------------------------------------------------
1 | // Polyline.swift
2 | //
3 | // Copyright (c) 2015 Raphaël Mor
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Foundation
24 | #if canImport(CoreLocation)
25 | import CoreLocation
26 | #endif
27 |
28 | #if canImport(CoreLocation)
29 | /**
30 | A geographic coordinate.
31 |
32 | This is a compatibility shim to keep the library’s public interface consistent between Apple and non-Apple platforms that lack Core Location. On Apple platforms, you can use `CLLocationCoordinate2D` anywhere you see this type.
33 | */
34 | public typealias LocationCoordinate2D = CLLocationCoordinate2D
35 | #else
36 | /**
37 | A geographic coordinate.
38 | */
39 | public struct LocationCoordinate2D {
40 | public let latitude: Double
41 | public let longitude: Double
42 |
43 | public init(latitude: Double, longitude: Double) {
44 | self.latitude = latitude
45 | self.longitude = longitude
46 | }
47 | }
48 | #endif
49 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcshareddata/xcschemes/PolylineWatch.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
52 |
53 |
59 |
60 |
66 |
67 |
68 |
69 |
71 |
72 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcuserdata/rmor.xcuserdatad/xcschemes/Polyline.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
79 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcshareddata/xcschemes/PolylineTV.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
42 |
48 |
49 |
50 |
51 |
52 |
62 |
63 |
69 |
70 |
71 |
72 |
78 |
79 |
85 |
86 |
87 |
88 |
90 |
91 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcshareddata/xcschemes/PolylineMac.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
42 |
48 |
49 |
50 |
51 |
52 |
62 |
63 |
69 |
70 |
71 |
72 |
78 |
79 |
85 |
86 |
87 |
88 |
90 |
91 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcshareddata/xcschemes/Polyline.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
38 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
64 |
70 |
71 |
72 |
73 |
79 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/xcuserdata/rmor.xcuserdatad/xcschemes/PolylineTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
79 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/Polyline.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint Polyline.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 |
11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
12 | #
13 | # These will help people to find your library, and whilst it
14 | # can feel like a chore to fill in it's definitely to your advantage. The
15 | # summary should be tweet-length, and the description more in depth.
16 | #
17 |
18 | s.name = "Polyline"
19 | s.version = "5.1.0"
20 | s.summary = "Polyline encoder / decoder in swift"
21 |
22 | s.description = <<-DESC
23 | A Google Polyline encoder / decoder in swift
24 | * Encodes Polyline from [CLLocation] or from [CLLocationCoordinate2D]
25 | * Decodes Polyline to [CLLocation] or to [CLLocationCoordinate2D]
26 | * Encodes/Decodes associated levels
27 | DESC
28 |
29 | s.homepage = "https://github.com/raphaelmor/Polyline"
30 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
31 |
32 |
33 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
34 | #
35 | # Licensing your code is important. See http://choosealicense.com for more info.
36 | # CocoaPods will detect a license file if there is a named LICENSE*
37 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
38 | #
39 |
40 | s.license = { :type => "MIT", :file => "LICENSE.txt" }
41 |
42 |
43 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
44 | #
45 | # Specify the authors of the library, with email addresses. Email addresses
46 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
47 | # accepts just a name if you'd rather not provide an email address.
48 | #
49 | # Specify a social_media_url where others can refer to, for example a twitter
50 | # profile URL.
51 | #
52 |
53 | s.author = { "Raphaël Mor" => "raphael.mor@gmail.com" }
54 | s.social_media_url = "http://twitter.com/raphaelmor"
55 |
56 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
57 | #
58 | # If this Pod runs only on iOS or OS X, then specify the platform and
59 | # the deployment target. You can optionally include the target after the platform.
60 | #
61 |
62 | s.ios.deployment_target = "12.0"
63 | s.osx.deployment_target = "10.14"
64 | s.watchos.deployment_target = "5.0"
65 | s.tvos.deployment_target = "12.0"
66 |
67 |
68 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
69 | #
70 | # Specify the location from where the source should be retrieved.
71 | # Supports git, hg, bzr, svn and HTTP.
72 | #
73 |
74 | s.source = { :git => "https://github.com/raphaelmor/Polyline.git", :tag => "v#{s.version.to_s}" }
75 |
76 |
77 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
78 | #
79 | # CocoaPods is smart about how it includes source code. For source files
80 | # giving a folder will include any swift, h, m, mm, c & cpp files.
81 | # For header files it will include any header in the folder.
82 | # Not including the public_header_files will make all headers public.
83 | #
84 |
85 | s.source_files = "Sources/Polyline"
86 |
87 | # s.public_header_files = "Classes/**/*.h"
88 |
89 |
90 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
91 | #
92 | # A list of resources included with the Pod. These are copied into the
93 | # target bundle with a build phase script. Anything else will be cleaned.
94 | # You can preserve files from being cleaned, please don't preserve
95 | # non-essential files like tests, examples and documentation.
96 | #
97 |
98 | # s.resource = "icon.png"
99 | # s.resources = "Resources/*.png"
100 |
101 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
102 |
103 |
104 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
105 | #
106 | # Link your library with frameworks, or libraries. Libraries do not include
107 | # the lib prefix of their name.
108 | #
109 |
110 | # s.framework = "SomeFramework"
111 | # s.frameworks = "SomeFramework", "AnotherFramework"
112 |
113 | # s.library = "iconv"
114 | # s.libraries = "iconv", "xml2"
115 |
116 |
117 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
118 | #
119 | # If your library depends on compiler flags you can set them in the xcconfig hash
120 | # where they will only apply to your library. If you depend on other Podspecs
121 | # you can include multiple dependencies to ensure it works.
122 |
123 | s.requires_arc = true
124 | s.swift_version = "5.0"
125 |
126 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
127 | # s.dependency "JSONKit", "~> 1.4"
128 |
129 | end
130 |
--------------------------------------------------------------------------------
/Tests/PolylineTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | #if !canImport(ObjectiveC)
2 | import XCTest
3 |
4 | extension FunctionalPolylineTests {
5 | // DO NOT MODIFY: This is autogenerated, use:
6 | // `swift test --generate-linuxmain`
7 | // to regenerate.
8 | static let __allTests__FunctionalPolylineTests = [
9 | ("testAnotherValidPolylineShouldReturnValidLocationArray", testAnotherValidPolylineShouldReturnValidLocationArray),
10 | ("testDecodingPolyline", testDecodingPolyline),
11 | ("testEmptyArrayShouldBeEmptyString", testEmptyArrayShouldBeEmptyString),
12 | ("testEmptyLevelsShouldBeEmptyLevelArray", testEmptyLevelsShouldBeEmptyLevelArray),
13 | ("testEmptylevelsShouldBeEmptyString", testEmptylevelsShouldBeEmptyString),
14 | ("testEmptyPolylineShouldBeEmptyLocationArray", testEmptyPolylineShouldBeEmptyLocationArray),
15 | ("testHighNegativeRoundedValuesShouldBeEncodedProperly", testHighNegativeRoundedValuesShouldBeEncodedProperly),
16 | ("testHighRoundedValuesShouldBeEncodedProperly", testHighRoundedValuesShouldBeEncodedProperly),
17 | ("testInvalidLevelsShouldReturnNilLevelArray", testInvalidLevelsShouldReturnNilLevelArray),
18 | ("testInvalidPolylineShouldReturnEmptyLocationArray", testInvalidPolylineShouldReturnEmptyLocationArray),
19 | ("testLocationsArrayShouldBeEncodedProperly", testLocationsArrayShouldBeEncodedProperly),
20 | ("testLowNegativeRoundedValuesShouldBeEncodedProperly", testLowNegativeRoundedValuesShouldBeEncodedProperly),
21 | ("testLowRoundedValuesShouldBeEncodedProperly", testLowRoundedValuesShouldBeEncodedProperly),
22 | ("testMidNegativeRoundedValuesShouldBeEncodedProperly", testMidNegativeRoundedValuesShouldBeEncodedProperly),
23 | ("testMidRoundedValuesShouldBeEncodedProperly", testMidRoundedValuesShouldBeEncodedProperly),
24 | ("testMinimalNegativeDifferenceShouldBeEncodedProperly", testMinimalNegativeDifferenceShouldBeEncodedProperly),
25 | ("testMinimalPositiveDifferenceShouldBeEncodedProperly", testMinimalPositiveDifferenceShouldBeEncodedProperly),
26 | ("testSmallDecrementLocationArrayShouldBeEncodedProperly", testSmallDecrementLocationArrayShouldBeEncodedProperly),
27 | ("testSmallIncrementLocationArrayShouldBeEncodedProperly", testSmallIncrementLocationArrayShouldBeEncodedProperly),
28 | ("testValidlevelsShouldBeEncodedProperly", testValidlevelsShouldBeEncodedProperly),
29 | ("testValidLevelsShouldReturnValidLevelArray", testValidLevelsShouldReturnValidLevelArray),
30 | ("testValidPolylineShouldReturnValidLocationArray", testValidPolylineShouldReturnValidLocationArray),
31 | ("testZeroShouldBeEncodedProperly", testZeroShouldBeEncodedProperly),
32 | ]
33 | }
34 |
35 | extension PolylineTests {
36 | // DO NOT MODIFY: This is autogenerated, use:
37 | // `swift test --generate-linuxmain`
38 | // to regenerate.
39 | static let __allTests__PolylineTests = [
40 | ("testAnotherValidPolylineShouldReturnValidLocationArray", testAnotherValidPolylineShouldReturnValidLocationArray),
41 | ("testCoordinatesEncoding", testCoordinatesEncoding),
42 | ("testEmptyArrayShouldBeEmptyString", testEmptyArrayShouldBeEmptyString),
43 | ("testEmptyLevelsShouldBeEmptyLevelArray", testEmptyLevelsShouldBeEmptyLevelArray),
44 | ("testEmptylevelsShouldBeEmptyString", testEmptylevelsShouldBeEmptyString),
45 | ("testEmptyPolylineConvertionShouldBeEmptyMKPolyline", testEmptyPolylineConvertionShouldBeEmptyMKPolyline),
46 | ("testEmptyPolylineShouldBeEmptyLocationArray", testEmptyPolylineShouldBeEmptyLocationArray),
47 | ("testHighNegativeRoundedValuesShouldBeEncodedProperly", testHighNegativeRoundedValuesShouldBeEncodedProperly),
48 | ("testHighRoundedValuesShouldBeEncodedProperly", testHighRoundedValuesShouldBeEncodedProperly),
49 | ("testInvalidLevelsShouldReturnNilLevelArray", testInvalidLevelsShouldReturnNilLevelArray),
50 | ("testInvalidPolylineShouldReturnNil", testInvalidPolylineShouldReturnNil),
51 | ("testLevelDecoding", testLevelDecoding),
52 | ("testLevelEncoding", testLevelEncoding),
53 | ("testLimitValueIsProperlyEncoded", testLimitValueIsProperlyEncoded),
54 | ("testLocationsArrayShouldBeEncodedProperly", testLocationsArrayShouldBeEncodedProperly),
55 | ("testLocationsEncoding", testLocationsEncoding),
56 | ("testLowNegativeRoundedValuesShouldBeEncodedProperly", testLowNegativeRoundedValuesShouldBeEncodedProperly),
57 | ("testLowRoundedValuesShouldBeEncodedProperly", testLowRoundedValuesShouldBeEncodedProperly),
58 | ("testMidNegativeRoundedValuesShouldBeEncodedProperly", testMidNegativeRoundedValuesShouldBeEncodedProperly),
59 | ("testMidRoundedValuesShouldBeEncodedProperly", testMidRoundedValuesShouldBeEncodedProperly),
60 | ("testMinimalNegativeDifferenceShouldBeEncodedProperly", testMinimalNegativeDifferenceShouldBeEncodedProperly),
61 | ("testMinimalPositiveDifferenceShouldBeEncodedProperly", testMinimalPositiveDifferenceShouldBeEncodedProperly),
62 | ("testNillevelsShouldBeNil", testNillevelsShouldBeNil),
63 | ("testPerformances", testPerformances),
64 | ("testPolylineConvertionToMKPolyline", testPolylineConvertionToMKPolyline),
65 | ("testPolylineConvertionToMKPolylineWhenEncodingFailed", testPolylineConvertionToMKPolylineWhenEncodingFailed),
66 | ("testPolylineDecodingToCoordinate", testPolylineDecodingToCoordinate),
67 | ("testPolylineDecodingToLocations", testPolylineDecodingToLocations),
68 | ("testPrecision", testPrecision),
69 | ("testPrecisionIsUsedProperly", testPrecisionIsUsedProperly),
70 | ("testPrecisionShouldBeUsedProperlyInDecoding", testPrecisionShouldBeUsedProperlyInDecoding),
71 | ("testPrecisionShouldBeUsedProperlyInEncoding", testPrecisionShouldBeUsedProperlyInEncoding),
72 | ("testSmallDecrementLocationArrayShouldBeEncodedProperly", testSmallDecrementLocationArrayShouldBeEncodedProperly),
73 | ("testSmallIncrementLocationArrayShouldBeEncodedProperly", testSmallIncrementLocationArrayShouldBeEncodedProperly),
74 | ("testSmallNegativeDifferencesShouldBeEncodedProperly", testSmallNegativeDifferencesShouldBeEncodedProperly),
75 | ("testValidlevelsShouldBeEncodedProperly", testValidlevelsShouldBeEncodedProperly),
76 | ("testValidLevelsShouldReturnValidLevelArray", testValidLevelsShouldReturnValidLevelArray),
77 | ("testValidPolylineShouldReturnValidLocationArray", testValidPolylineShouldReturnValidLocationArray),
78 | ("testZeroShouldBeEncodedProperly", testZeroShouldBeEncodedProperly),
79 | ]
80 | }
81 |
82 | public func __allTests() -> [XCTestCaseEntry] {
83 | return [
84 | testCase(FunctionalPolylineTests.__allTests__FunctionalPolylineTests),
85 | testCase(PolylineTests.__allTests__PolylineTests),
86 | ]
87 | }
88 | #endif
89 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | [](https://travis-ci.org/raphaelmor/Polyline)
6 | [](http://cocoadocs.org/docsets/Polyline)
7 | 
8 | [](https://github.com/raphaelmor/Polyline/blob/master/LICENSE.txt)
9 |
10 | Polyline encoder / decoder in Swift
11 |
12 | 1. [Features](#features)
13 | 2. [Requirements](#requirements)
14 | 3. [Integration](#integration)
15 | 4. [Usage](#usage)
16 | 5. [Notes](#notes)
17 | 6. [Contributors](#contributors)
18 | 7. [License](#license)
19 |
20 | ## Features
21 |
22 | - Encode a `CLLocationCoordinate2D` array to a polyline
23 | - Decode a polyline to an array of `CLLocationCoordinate2D`
24 | - Encode a `CLLocation` array to a polyline
25 | - Decode a polyline to an array of `CLLocation`
26 | - Encode/Decode associated levels (optional)
27 | - 100% Unit Test Coverage
28 | - Complete Documentation
29 | - Continuous integration with [Travis CI](http://travis-ci.org)
30 | - CocoaPod available
31 | - Convert to `MKPolyline`
32 |
33 | ### Planned for future releases
34 |
35 | - Convert to `GMSPolyline`
36 | - Example project
37 | - Filter locations available at a specific level
38 |
39 | ### Planned when support is available :
40 |
41 | - Code Coverage with [Coveralls](https://coveralls.io)
42 |
43 | ## Requirements
44 |
45 | - Xcode 11+
46 | - iOS 12.0+ / Mac OS X 10.14+ / tvOS 12.0+ / watchOS 5.0+ / Linux
47 | - Swift 5.0
48 |
49 | ---
50 |
51 |
52 | ## Integration
53 | To use this library in your project you can use CocoaPods, Carthage, Swift Package Manager, and/or integrate it manually :
54 |
55 | ### CocoaPods
56 | You can integrate Polyline in your `Podfile` like this:
57 |
58 | ```
59 | pod 'Polyline', '~> 5.0'
60 | ```
61 |
62 | ### Carthage
63 | You can integrate Polyline in your `Cartfile` like this:
64 |
65 | ```
66 | github "raphaelmor/Polyline" ~> 5.0
67 | ```
68 |
69 | ### Swift Package Manager
70 | To integrate Polyline into an application using [Swift Package Manager](https://swift.org/package-manager/) within Xcode:
71 |
72 | 1. Go to File ‣ Swift Packages ‣ Add Package Dependency.
73 | 2. Enter `https://github.com/raphaelmor/Polyline.git` as the package repository and click Next.
74 | 3. Set Rules to Version, Up to Next Major, and enter `5.0.2` as the minimum version requirement. Click Next.
75 |
76 | Or to integrate Polyline into another Swift package, add the following package to the `dependencies` in your Package.swift file:
77 |
78 | ```swift
79 | .package(url: "https://github.com/raphaelmor/Polyline.git", from: "5.0.2")
80 | ```
81 |
82 | ### Manual
83 |
84 | To install Polyline manually, add Polyline.xcodeproj to an Xcode workspace, then link your application to Polyline.framework.
85 |
86 | It is technically possible to install Polyline by adding Polyline.swift and CoreLocation.swift directly to your project, but this approach is not recommended as it may omit important files in the future.
87 |
88 | ## Usage
89 |
90 | ### Polyline Encoding
91 |
92 | Using `[CLLocationCoordinate2D]` (recommended) :
93 |
94 | ```swift
95 | let coordinates = [CLLocationCoordinate2D(latitude: 40.2349727, longitude: -3.7707443),
96 | CLLocationCoordinate2D(latitude: 44.3377999, longitude: 1.2112933)]
97 |
98 | let polyline = Polyline(coordinates: coordinates)
99 | let encodedPolyline: String = polyline.encodedPolyline
100 |
101 | // Or for a functional approach :
102 | let encodedPolyline: String = encodeCoordinates(coordinates)
103 | ```
104 |
105 | Using `[CLLocation]` :
106 |
107 | ```swift
108 | let locations = [CLLocation(latitude: 40.2349727, longitude: -3.7707443),
109 | CLLocation(latitude: 44.3377999, longitude: 1.2112933)]
110 |
111 | let polyline = Polyline(locations: locations)
112 | let encodedPolyline: String = polyline.encodedPolyline
113 |
114 | // Or for a functional approach :
115 | let encodedPolyline: String = encodeLocations(locations)
116 | ```
117 |
118 | You can encode levels too :
119 |
120 | ```swift
121 | let levels: [UInt32] = [0,1,2,255]
122 |
123 | let polyline = Polyline(coordinates: coordinates, levels: levels)
124 | let encodedLevels: String? = polyline.encodedLevels
125 |
126 | // Or for a functional approach :
127 | let encodedLevels: String = encodedLevels(levels)
128 | ```
129 |
130 |
131 | ### Polyline Decoding
132 |
133 | You can decode to `[CLLocationCoordinate2D]` (recommended) :
134 |
135 | ```swift
136 | let polyline = Polyline(encodedPolyline: "qkqtFbn_Vui`Xu`l]")
137 | let decodedCoordinates: [CLLocationCoordinate2D]? = polyline.coordinates
138 |
139 | // Or for a functional approach :
140 | let coordinates: [CLLocationCoordinate2D]? = decodePolyline("qkqtFbn_Vui`Xu`l]")
141 | ```
142 |
143 | You can also decode to `[CLLocation]` :
144 |
145 | ```swift
146 | let polyline = Polyline(encodedPolyline: "qkqtFbn_Vui`Xu`l]")
147 | let decodedLocations: [CLLocation]? = polyline.locations
148 |
149 | // Or for a functional approach :
150 | let locations: [CLLocation]? = decodePolyline("qkqtFbn_Vui`Xu`l]")
151 | ```
152 |
153 | You can decode levels too :
154 |
155 | ```swift
156 | let polyline = Polyline(encodedPolyline: "qkqtFbn_Vui`Xu`l]", encodedLevels: "BA")
157 | let decodedLevels: [UInt32]? = polyline.levels
158 |
159 | // Or for a functional approach :
160 | let levels: [UInt32]? = decodeLevels("BA")
161 | ```
162 |
163 | ### Polyline Precision
164 |
165 | Default precision is 1e5 : 0.12345 (5 digit precision used by Google), but you can specify your own precision in all API methods (and functions).
166 |
167 | ```swift
168 | // OSRM uses a 6 digit precision
169 | let polyline = Polyline(encodedPolyline: "ak{hRak{hR", precision: 1e6)
170 | ```
171 |
172 |
173 |
174 | ## Notes
175 | This library tries to have consistent results with polylines generated by the [Google Maps iOS SDK](https://developers.google.com/maps/documentation/ios/).
176 | The online tool for [encoding polylines](https://developers.google.com/maps/documentation/utilities/polylineutility) has some minor inconsistencies regarding rounding (for example, 0.000015 is rounded to 0.00002 for latitudes, but 0.00001 for longitudes).
177 |
178 | This codes tries to adhere to the [GitHub Swift Style Guide](https://github.com/github/swift-style-guide)
179 |
180 | ## Contributors
181 |
182 | - [Raphaël Mor](http://github.com/raphaelmor) ([@raphaelmor](https://twitter.com/raphaelmor)): Creator
183 | - [Tom Taylor](https://tomtaylor.co.uk): Maintainer
184 | - [Minh Nguyễn](https://github.com/1ec5): Maintainer
185 |
186 | ## License
187 | Polyline is released under an MIT license. See [LICENSE.txt](https://github.com/raphaelmor/Polyline/blob/master/LICENSE.txt) for more information.
188 |
--------------------------------------------------------------------------------
/Tests/PolylineTests/FunctionalPolylineTests.swift:
--------------------------------------------------------------------------------
1 | // PolylineTests.swift
2 | //
3 | // Copyright (c) 2015 Raphaël Mor
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | #if canImport(CoreLocation)
24 | import CoreLocation
25 | #endif
26 | import XCTest
27 |
28 | import Polyline
29 |
30 | private let COORD_EPSILON: Double = 0.00001
31 |
32 | class FunctionalPolylineTests : XCTestCase {
33 |
34 | // MARK:- Encoding Coordinates
35 |
36 | func testEmptyArrayShouldBeEmptyString() {
37 | XCTAssertEqual(encodeCoordinates([]), "")
38 | }
39 |
40 | func testZeroShouldBeEncodedProperly() {
41 | let coordinates = [CLLocationCoordinate2D(latitude: 0, longitude: 0)]
42 | XCTAssertEqual(encodeCoordinates(coordinates), "??")
43 | }
44 |
45 | func testMinimalPositiveDifferenceShouldBeEncodedProperly() {
46 | let coordinates = [CLLocationCoordinate2D(latitude: 0.00001, longitude: 0.00001)]
47 | XCTAssertEqual(encodeCoordinates(coordinates), "AA")
48 | }
49 |
50 | func testLowRoundedValuesShouldBeEncodedProperly() {
51 | let coordinates = [CLLocationCoordinate2D(latitude: 0.000014, longitude: 0.000014)]
52 | XCTAssertEqual(encodeCoordinates(coordinates), "AA")
53 | }
54 |
55 | func testMidRoundedValuesShouldBeEncodedProperly() {
56 | let coordinates = [CLLocationCoordinate2D(latitude: 0.000015, longitude: 0.000015)]
57 | XCTAssertEqual(encodeCoordinates(coordinates), "CC")
58 | }
59 |
60 | func testHighRoundedValuesShouldBeEncodedProperly() {
61 | let coordinates = [CLLocationCoordinate2D(latitude: 0.000016, longitude: 0.000016)]
62 | XCTAssertEqual(encodeCoordinates(coordinates), "CC")
63 | }
64 |
65 | func testMinimalNegativeDifferenceShouldBeEncodedProperly() {
66 | let coordinates = [CLLocationCoordinate2D(latitude: -0.00001, longitude: -0.00001)]
67 | XCTAssertEqual(encodeCoordinates(coordinates), "@@")
68 | }
69 |
70 | func testLowNegativeRoundedValuesShouldBeEncodedProperly() {
71 | let coordinates = [CLLocationCoordinate2D(latitude: -0.000014, longitude: -0.000014)]
72 | XCTAssertEqual(encodeCoordinates(coordinates), "@@")
73 | }
74 |
75 | func testMidNegativeRoundedValuesShouldBeEncodedProperly() {
76 | let coordinates = [CLLocationCoordinate2D(latitude: -0.000015, longitude: -0.000015)]
77 | XCTAssertEqual(encodeCoordinates(coordinates), "BB")
78 | }
79 |
80 | func testHighNegativeRoundedValuesShouldBeEncodedProperly() {
81 | let coordinates = [CLLocationCoordinate2D(latitude: -0.000016, longitude: -0.000016)]
82 | XCTAssertEqual(encodeCoordinates(coordinates), "BB")
83 | }
84 |
85 | func testSmallIncrementLocationArrayShouldBeEncodedProperly() {
86 | let coordinates = [CLLocationCoordinate2D(latitude: 0.00001, longitude: 0.00001),
87 | CLLocationCoordinate2D(latitude: 0.00002, longitude: 0.00002)]
88 | XCTAssertEqual(encodeCoordinates(coordinates), "AAAA")
89 | }
90 |
91 | func testSmallDecrementLocationArrayShouldBeEncodedProperly() {
92 | let coordinates = [CLLocationCoordinate2D(latitude: 0.00001, longitude: 0.00001),
93 | CLLocationCoordinate2D(latitude: 0.00000, longitude: 0.00000)]
94 | XCTAssertEqual(encodeCoordinates(coordinates), "AA@@")
95 | }
96 |
97 | // MARK: - Decoding Coordinates
98 |
99 | func testEmptyPolylineShouldBeEmptyLocationArray() {
100 | let coordinates: [CLLocationCoordinate2D] = decodePolyline("")!
101 |
102 | XCTAssertEqual(coordinates.count, 0)
103 | }
104 |
105 | func testInvalidPolylineShouldReturnEmptyLocationArray() {
106 | XCTAssertNil(decodePolyline("invalidPolylineString") as [CLLocationCoordinate2D]?)
107 | }
108 |
109 | func testValidPolylineShouldReturnValidLocationArray() {
110 | let coordinates: [CLLocationCoordinate2D] = decodePolyline("_p~iF~ps|U_ulLnnqC_mqNvxq`@")!
111 |
112 | XCTAssertEqual(coordinates.count, 3)
113 | XCTAssertEqual(coordinates[0].latitude, 38.5, accuracy: COORD_EPSILON)
114 | XCTAssertEqual(coordinates[0].longitude, -120.2, accuracy: COORD_EPSILON)
115 | XCTAssertEqual(coordinates[1].latitude, 40.7, accuracy: COORD_EPSILON)
116 | XCTAssertEqual(coordinates[1].longitude, -120.95, accuracy: COORD_EPSILON)
117 | XCTAssertEqual(coordinates[2].latitude, 43.252, accuracy: COORD_EPSILON)
118 | XCTAssertEqual(coordinates[2].longitude, -126.453, accuracy: COORD_EPSILON)
119 | }
120 |
121 | func testAnotherValidPolylineShouldReturnValidLocationArray() {
122 | let coordinates: [CLLocationCoordinate2D] = decodePolyline("_ojiHa`tLh{IdCw{Gwc_@")!
123 |
124 | XCTAssertEqual(coordinates.count, 3)
125 | XCTAssertEqual(coordinates[0].latitude, 48.8832, accuracy: COORD_EPSILON)
126 | XCTAssertEqual(coordinates[0].longitude, 2.23761, accuracy: COORD_EPSILON)
127 | XCTAssertEqual(coordinates[1].latitude, 48.82747, accuracy: COORD_EPSILON)
128 | XCTAssertEqual(coordinates[1].longitude, 2.23694, accuracy: COORD_EPSILON)
129 | XCTAssertEqual(coordinates[2].latitude, 48.87303, accuracy: COORD_EPSILON)
130 | XCTAssertEqual(coordinates[2].longitude, 2.40154, accuracy: COORD_EPSILON)
131 | }
132 |
133 | // MARK:- Encoding levels
134 |
135 | func testEmptylevelsShouldBeEmptyString() {
136 | XCTAssertEqual(encodeLevels([]), "")
137 | }
138 |
139 | func testValidlevelsShouldBeEncodedProperly() {
140 | XCTAssertEqual(encodeLevels([0,1,2,3]), "?@AB")
141 | }
142 |
143 | // MARK:- Decoding levels
144 |
145 | func testEmptyLevelsShouldBeEmptyLevelArray() {
146 | if let resultArray = decodeLevels("") {
147 | XCTAssertEqual(resultArray.count, 0)
148 | } else {
149 | XCTFail("Level array should not be nil for empty string")
150 | }
151 | }
152 |
153 | func testInvalidLevelsShouldReturnNilLevelArray() {
154 | if let _ = decodeLevels("invalidLevelString") {
155 | XCTFail("Level array should be nil for invalid string")
156 | } else {
157 | //Success
158 | }
159 | }
160 |
161 | func testValidLevelsShouldReturnValidLevelArray() {
162 | if let resultArray = decodeLevels("?@AB~F") {
163 | XCTAssertEqual(resultArray.count, 5)
164 | XCTAssertEqual(resultArray[0], UInt32(0))
165 | XCTAssertEqual(resultArray[1], UInt32(1))
166 | XCTAssertEqual(resultArray[2], UInt32(2))
167 | XCTAssertEqual(resultArray[3], UInt32(3))
168 | XCTAssertEqual(resultArray[4], UInt32(255))
169 |
170 | } else {
171 | XCTFail("Valid Levels should be decoded properly")
172 | }
173 | }
174 |
175 | // MARK: - Encoding Locations
176 | func testLocationsArrayShouldBeEncodedProperly() {
177 | #if canImport(CoreLocation)
178 | let locations = [CLLocation(latitude: 0.00001, longitude: 0.00001),
179 | CLLocation(latitude: 0.00000, longitude: 0.00000)]
180 |
181 | XCTAssertEqual(encodeLocations(locations), "AA@@")
182 | #endif
183 | }
184 |
185 | func testDecodingPolyline() {
186 | let coordinates = decodePolyline("afvnFdrebO@o@", precision: 1e5) as [LocationCoordinate2D]?
187 | XCTAssertNotNil(coordinates)
188 | XCTAssertEqual(coordinates?.count, 2)
189 | XCTAssertEqual(coordinates?.first?.latitude ?? 0.0, 39.27665, accuracy: 1e-5)
190 | XCTAssertEqual(coordinates?.first?.longitude ?? 0.0, -84.411389, accuracy: 1e-5)
191 | XCTAssertEqual(coordinates?.last?.latitude ?? 0.0, 39.276635, accuracy: 1e-5)
192 | XCTAssertEqual(coordinates?.last?.longitude ?? 0.0, -84.411148, accuracy: 1e-5)
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/Sources/Polyline/Polyline.swift:
--------------------------------------------------------------------------------
1 | // Polyline.swift
2 | //
3 | // Copyright (c) 2015 Raphaël Mor
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | import Foundation
24 | #if canImport(CoreLocation)
25 | import CoreLocation
26 | #endif
27 | #if canImport(MapKit) && !os(watchOS)
28 | import MapKit
29 | #endif
30 |
31 | // MARK: - Public Classes -
32 |
33 | /// This class can be used for :
34 | ///
35 | /// - Encoding an [CLLocation] or a [CLLocationCoordinate2D] to a polyline String
36 | /// - Decoding a polyline String to an [CLLocation] or a [CLLocationCoordinate2D]
37 | /// - Encoding / Decoding associated levels
38 | ///
39 | /// it is aims to produce the same results as google's iOS sdk not as the online
40 | /// tool which is fuzzy when it comes to rounding values
41 | ///
42 | /// it is based on google's algorithm that can be found here :
43 | ///
44 | /// :see: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
45 | public struct Polyline {
46 |
47 | /// The array of coordinates (nil if polyline cannot be decoded)
48 | public let coordinates: [LocationCoordinate2D]?
49 | /// The encoded polyline
50 | public let encodedPolyline: String
51 |
52 | /// The array of levels (nil if cannot be decoded, or is not provided)
53 | public let levels: [UInt32]?
54 | /// The encoded levels (nil if cannot be encoded, or is not provided)
55 | public let encodedLevels: String?
56 |
57 | /// The array of location (computed from coordinates)
58 | #if canImport(CoreLocation)
59 | public var locations: [CLLocation]? {
60 | return self.coordinates.map(toLocations)
61 | }
62 | #endif
63 |
64 | #if canImport(MapKit) && !os(watchOS)
65 | /// Convert polyline to MKPolyline to use with MapKit (nil if polyline cannot be decoded)
66 | @available(tvOS 9.2, *)
67 | public var mkPolyline: MKPolyline? {
68 | guard let coordinates = self.coordinates else { return nil }
69 | let mkPolyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
70 | return mkPolyline
71 | }
72 | #endif
73 |
74 | // MARK: - Public Methods -
75 |
76 | /// This designated initializer encodes a `[CLLocationCoordinate2D]`
77 | ///
78 | /// - parameter coordinates: The `Array` of `LocationCoordinate2D`s (that is, `CLLocationCoordinate2D`s) that you want to encode
79 | /// - parameter levels: The optional `Array` of levels that you want to encode (default: `nil`)
80 | /// - parameter precision: The precision used for encoding (default: `1e5`)
81 | public init(coordinates: [LocationCoordinate2D], levels: [UInt32]? = nil, precision: Double = 1e5) {
82 |
83 | self.coordinates = coordinates
84 | self.levels = levels
85 |
86 | encodedPolyline = encodeCoordinates(coordinates, precision: precision)
87 |
88 | encodedLevels = levels.map(encodeLevels)
89 | }
90 |
91 | /// This designated initializer decodes a polyline `String`
92 | ///
93 | /// - parameter encodedPolyline: The polyline that you want to decode
94 | /// - parameter encodedLevels: The levels that you want to decode (default: `nil`)
95 | /// - parameter precision: The precision used for decoding (default: `1e5`)
96 | public init(encodedPolyline: String, encodedLevels: String? = nil, precision: Double = 1e5) {
97 |
98 | self.encodedPolyline = encodedPolyline
99 | self.encodedLevels = encodedLevels
100 |
101 | coordinates = decodePolyline(encodedPolyline, precision: precision)
102 |
103 | levels = self.encodedLevels.flatMap(decodeLevels)
104 | }
105 |
106 | #if canImport(CoreLocation)
107 | /// This init encodes a `[CLLocation]`
108 | ///
109 | /// - parameter locations: The `Array` of `CLLocation` that you want to encode
110 | /// - parameter levels: The optional array of levels that you want to encode (default: `nil`)
111 | /// - parameter precision: The precision used for encoding (default: `1e5`)
112 | public init(locations: [CLLocation], levels: [UInt32]? = nil, precision: Double = 1e5) {
113 |
114 | let coordinates = toCoordinates(locations)
115 | self.init(coordinates: coordinates, levels: levels, precision:precision)
116 | }
117 | #endif
118 | }
119 |
120 | // MARK: - Public Functions -
121 |
122 | /// This function encodes an `[CLLocationCoordinate2D]` to a `String`
123 | ///
124 | /// - parameter coordinates: The `Array` of `LocationCoordinate2D`s (that is, `CLLocationCoordinate2D`s) that you want to encode
125 | /// - parameter precision: The precision used to encode coordinates (default: `1e5`)
126 | ///
127 | /// - returns: A `String` representing the encoded Polyline
128 | public func encodeCoordinates(_ coordinates: [LocationCoordinate2D], precision: Double = 1e5) -> String {
129 |
130 | var previousCoordinate = IntegerCoordinates(0, 0)
131 | var encodedPolyline = ""
132 |
133 | for coordinate in coordinates {
134 | let intLatitude = Int(round(coordinate.latitude * precision))
135 | let intLongitude = Int(round(coordinate.longitude * precision))
136 |
137 | let coordinatesDifference = (intLatitude - previousCoordinate.latitude, intLongitude - previousCoordinate.longitude)
138 |
139 | encodedPolyline += encodeCoordinate(coordinatesDifference)
140 |
141 | previousCoordinate = (intLatitude,intLongitude)
142 | }
143 |
144 | return encodedPolyline
145 | }
146 |
147 | #if canImport(CoreLocation)
148 | /// This function encodes an `[CLLocation]` to a `String`
149 | ///
150 | /// - parameter coordinates: The `Array` of `CLLocation` that you want to encode
151 | /// - parameter precision: The precision used to encode locations (default: `1e5`)
152 | ///
153 | /// - returns: A `String` representing the encoded Polyline
154 | public func encodeLocations(_ locations: [CLLocation], precision: Double = 1e5) -> String {
155 |
156 | return encodeCoordinates(toCoordinates(locations), precision: precision)
157 | }
158 | #endif
159 |
160 | /// This function encodes an `[UInt32]` to a `String`
161 | ///
162 | /// - parameter levels: The `Array` of `UInt32` levels that you want to encode
163 | ///
164 | /// - returns: A `String` representing the encoded Levels
165 | public func encodeLevels(_ levels: [UInt32]) -> String {
166 | return levels.reduce("") {
167 | $0 + encodeLevel($1)
168 | }
169 | }
170 |
171 | /// This function decodes a `String` to a `[CLLocationCoordinate2D]?`
172 | ///
173 | /// - parameter encodedPolyline: `String` representing the encoded Polyline
174 | /// - parameter precision: The precision used to decode coordinates (default: `1e5`)
175 | ///
176 | /// - returns: A `[CLLocationCoordinate2D]` representing the decoded polyline if valid, `nil` otherwise
177 | public func decodePolyline(_ encodedPolyline: String, precision: Double = 1e5) -> [LocationCoordinate2D]? {
178 | let data = encodedPolyline.data(using: .utf8)!
179 | return data.withUnsafeBytes { byteArray -> [LocationCoordinate2D]? in
180 | let length = data.count
181 | var position = 0
182 |
183 | var decodedCoordinates = [LocationCoordinate2D]()
184 |
185 | var lat = 0.0
186 | var lon = 0.0
187 |
188 | while position < length {
189 | do {
190 | let resultingLat = try decodeSingleCoordinate(byteArray: byteArray, length: length, position: &position, precision: precision)
191 | lat += resultingLat
192 |
193 | let resultingLon = try decodeSingleCoordinate(byteArray: byteArray, length: length, position: &position, precision: precision)
194 | lon += resultingLon
195 | } catch {
196 | return nil
197 | }
198 |
199 | decodedCoordinates.append(LocationCoordinate2D(latitude: lat, longitude: lon))
200 | }
201 |
202 | return decodedCoordinates
203 | }
204 | }
205 |
206 | #if canImport(CoreLocation)
207 | /// This function decodes a String to a [CLLocation]?
208 | ///
209 | /// - parameter encodedPolyline: String representing the encoded Polyline
210 | /// - parameter precision: The precision used to decode locations (default: 1e5)
211 | ///
212 | /// - returns: A [CLLocation] representing the decoded polyline if valid, nil otherwise
213 | public func decodePolyline(_ encodedPolyline: String, precision: Double = 1e5) -> [CLLocation]? {
214 |
215 | return decodePolyline(encodedPolyline, precision: precision).map(toLocations)
216 | }
217 | #endif
218 |
219 | /// This function decodes a `String` to an `[UInt32]`
220 | ///
221 | /// - parameter encodedLevels: The `String` representing the levels to decode
222 | ///
223 | /// - returns: A `[UInt32]` representing the decoded Levels if the `String` is valid, `nil` otherwise
224 | public func decodeLevels(_ encodedLevels: String) -> [UInt32]? {
225 | var remainingLevels = encodedLevels.unicodeScalars
226 | var decodedLevels = [UInt32]()
227 |
228 | while remainingLevels.count > 0 {
229 |
230 | do {
231 | let chunk = try extractNextChunk(&remainingLevels)
232 | let level = decodeLevel(chunk)
233 | decodedLevels.append(level)
234 | } catch {
235 | return nil
236 | }
237 | }
238 |
239 | return decodedLevels
240 | }
241 |
242 |
243 | // MARK: - Private -
244 |
245 | // MARK: Encode Coordinate
246 |
247 | private func encodeCoordinate(_ locationCoordinate: IntegerCoordinates) -> String {
248 |
249 | let latitudeString = encodeSingleComponent(locationCoordinate.latitude)
250 | let longitudeString = encodeSingleComponent(locationCoordinate.longitude)
251 |
252 | return latitudeString + longitudeString
253 | }
254 |
255 | private func encodeSingleComponent(_ value: Int) -> String {
256 |
257 | var intValue = value
258 |
259 | if intValue < 0 {
260 | intValue = intValue << 1
261 | intValue = ~intValue
262 | } else {
263 | intValue = intValue << 1
264 | }
265 |
266 | return encodeFiveBitComponents(intValue)
267 | }
268 |
269 | // MARK: Encode Levels
270 |
271 | private func encodeLevel(_ level: UInt32) -> String {
272 | return encodeFiveBitComponents(Int(level))
273 | }
274 |
275 | private func encodeFiveBitComponents(_ value: Int) -> String {
276 | var remainingComponents = value
277 |
278 | var fiveBitComponent = 0
279 | var returnString = String()
280 |
281 | repeat {
282 | fiveBitComponent = remainingComponents & 0x1F
283 |
284 | if remainingComponents >= 0x20 {
285 | fiveBitComponent |= 0x20
286 | }
287 |
288 | fiveBitComponent += 63
289 |
290 | let char = UnicodeScalar(fiveBitComponent)!
291 | returnString.append(String(char))
292 | remainingComponents = remainingComponents >> 5
293 | } while (remainingComponents != 0)
294 |
295 | return returnString
296 | }
297 |
298 | // MARK: Decode Coordinate
299 |
300 | // We use a byte array (UnsafePointer) here for performance reasons. Check with swift 2 if we can
301 | // go back to using [Int8]
302 | private func decodeSingleCoordinate(byteArray: UnsafeRawBufferPointer, length: Int, position: inout Int, precision: Double = 1e5) throws -> Double {
303 |
304 | guard position < length else { throw PolylineError.singleCoordinateDecodingError }
305 |
306 | let bitMask = Int8(0x1F)
307 |
308 | var coordinate: Int32 = 0
309 |
310 | var currentChar: Int8
311 | var componentCounter: Int32 = 0
312 | var component: Int32 = 0
313 |
314 | repeat {
315 | currentChar = Int8(byteArray[position]) - 63
316 | component = Int32(currentChar & bitMask)
317 | coordinate |= (component << (5*componentCounter))
318 | position += 1
319 | componentCounter += 1
320 | } while ((currentChar & 0x20) == 0x20) && (position < length) && (componentCounter < 6)
321 |
322 | if (componentCounter == 6) && ((currentChar & 0x20) == 0x20) {
323 | throw PolylineError.singleCoordinateDecodingError
324 | }
325 |
326 | if (coordinate & 0x01) == 0x01 {
327 | coordinate = ~(coordinate >> 1)
328 | } else {
329 | coordinate = coordinate >> 1
330 | }
331 |
332 | return Double(coordinate) / precision
333 | }
334 |
335 | // MARK: Decode Levels
336 |
337 | private func extractNextChunk(_ encodedString: inout String.UnicodeScalarView) throws -> String {
338 | var currentIndex = encodedString.startIndex
339 |
340 | while currentIndex != encodedString.endIndex {
341 | let currentCharacterValue = Int32(encodedString[currentIndex].value)
342 | if isSeparator(currentCharacterValue) {
343 | let extractedScalars = encodedString[encodedString.startIndex...currentIndex]
344 | encodedString = String.UnicodeScalarView(encodedString[encodedString.index(after: currentIndex).. UInt32 {
356 | let scalarArray = [] + encodedLevel.unicodeScalars
357 |
358 | return UInt32(agregateScalarArray(scalarArray))
359 | }
360 |
361 | private func agregateScalarArray(_ scalars: [UnicodeScalar]) -> Int32 {
362 | let lastValue = Int32(scalars.last!.value)
363 |
364 | let fiveBitComponents: [Int32] = scalars.map { scalar in
365 | let value = Int32(scalar.value)
366 | if value != lastValue {
367 | return (value - 63) ^ 0x20
368 | } else {
369 | return value - 63
370 | }
371 | }
372 |
373 | return Array(fiveBitComponents.reversed()).reduce(0) { ($0 << 5 ) | $1 }
374 | }
375 |
376 | // MARK: Utilities
377 |
378 | enum PolylineError: Error {
379 | case singleCoordinateDecodingError
380 | case chunkExtractingError
381 | }
382 |
383 | #if canImport(CoreLocation)
384 | private func toCoordinates(_ locations: [CLLocation]) -> [CLLocationCoordinate2D] {
385 | return locations.map {location in location.coordinate}
386 | }
387 |
388 | private func toLocations(_ coordinates: [CLLocationCoordinate2D]) -> [CLLocation] {
389 | return coordinates.map { coordinate in
390 | CLLocation(latitude:coordinate.latitude, longitude:coordinate.longitude)
391 | }
392 | }
393 | #endif
394 |
395 | private func isSeparator(_ value: Int32) -> Bool {
396 | return (value - 63) & 0x20 != 0x20
397 | }
398 |
399 | private typealias IntegerCoordinates = (latitude: Int, longitude: Int)
400 |
--------------------------------------------------------------------------------
/Tests/PolylineTests/PolylineTests.swift:
--------------------------------------------------------------------------------
1 | // PolylineTests.swift
2 | //
3 | // Copyright (c) 2015 Raphaël Mor
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | #if canImport(CoreLocation)
24 | import CoreLocation
25 | #endif
26 | import XCTest
27 |
28 | import Polyline
29 |
30 | private let COORD_EPSILON_1e5: Double = 0.00001
31 | private let COORD_EPSILON_1e6: Double = 0.000001
32 |
33 | class PolylineTests:XCTestCase {
34 |
35 | // MARK:- Encoding Coordinates
36 |
37 | func testEmptyArrayShouldBeEmptyString() {
38 | let sut = Polyline(coordinates: [])
39 | XCTAssertEqual(sut.encodedPolyline, "")
40 | }
41 |
42 | func testZeroShouldBeEncodedProperly() {
43 | let coordinates = [CLLocationCoordinate2D(latitude: 0, longitude: 0)]
44 |
45 | let sut = Polyline(coordinates: coordinates)
46 | XCTAssertEqual(sut.encodedPolyline, "??")
47 | }
48 |
49 | func testMinimalPositiveDifferenceShouldBeEncodedProperly() {
50 | let coordinates = [CLLocationCoordinate2D(latitude: 0.00001, longitude: 0.00001)]
51 |
52 | let sut = Polyline(coordinates: coordinates)
53 | XCTAssertEqual(sut.encodedPolyline, "AA")
54 | }
55 |
56 | func testLowRoundedValuesShouldBeEncodedProperly() {
57 | let coordinates = [CLLocationCoordinate2D(latitude: 0.000014, longitude: 0.000014)]
58 |
59 | let sut = Polyline(coordinates: coordinates)
60 | XCTAssertEqual(sut.encodedPolyline, "AA")
61 | }
62 |
63 | func testMidRoundedValuesShouldBeEncodedProperly() {
64 | let coordinates = [CLLocationCoordinate2D(latitude: 0.000015, longitude: 0.000015)]
65 |
66 | let sut = Polyline(coordinates: coordinates)
67 | XCTAssertEqual(sut.encodedPolyline, "CC")
68 | }
69 |
70 | func testHighRoundedValuesShouldBeEncodedProperly() {
71 | let coordinates = [CLLocationCoordinate2D(latitude: 0.000016, longitude: 0.000016)]
72 |
73 | let sut = Polyline(coordinates: coordinates)
74 | XCTAssertEqual(sut.encodedPolyline, "CC")
75 | }
76 |
77 | func testMinimalNegativeDifferenceShouldBeEncodedProperly() {
78 | let coordinates = [CLLocationCoordinate2D(latitude: -0.00001, longitude: -0.00001)]
79 |
80 | let sut = Polyline(coordinates: coordinates)
81 | XCTAssertEqual(sut.encodedPolyline, "@@")
82 | }
83 |
84 | func testLowNegativeRoundedValuesShouldBeEncodedProperly() {
85 | let coordinates = [CLLocationCoordinate2D(latitude: -0.000014, longitude: -0.000014)]
86 |
87 | let sut = Polyline(coordinates: coordinates)
88 | XCTAssertEqual(sut.encodedPolyline, "@@")
89 | }
90 |
91 | func testMidNegativeRoundedValuesShouldBeEncodedProperly() {
92 | let coordinates = [CLLocationCoordinate2D(latitude: -0.000015, longitude: -0.000015)]
93 |
94 | let sut = Polyline(coordinates: coordinates)
95 | XCTAssertEqual(sut.encodedPolyline, "BB")
96 | }
97 |
98 | func testHighNegativeRoundedValuesShouldBeEncodedProperly() {
99 | let coordinates = [CLLocationCoordinate2D(latitude: -0.000016, longitude: -0.000016)]
100 |
101 | let sut = Polyline(coordinates: coordinates)
102 | XCTAssertEqual(sut.encodedPolyline, "BB")
103 | }
104 |
105 | func testSmallIncrementLocationArrayShouldBeEncodedProperly() {
106 | let coordinates = [CLLocationCoordinate2D(latitude: 0.00001, longitude: 0.00001),
107 | CLLocationCoordinate2D(latitude: 0.00002, longitude: 0.00002)]
108 |
109 | let sut = Polyline(coordinates: coordinates)
110 | XCTAssertEqual(sut.encodedPolyline, "AAAA")
111 | }
112 |
113 | func testSmallDecrementLocationArrayShouldBeEncodedProperly() {
114 | let coordinates = [CLLocationCoordinate2D(latitude: 0.00001, longitude: 0.00001),
115 | CLLocationCoordinate2D(latitude: 0.00000, longitude: 0.00000)]
116 |
117 | let sut = Polyline(coordinates: coordinates)
118 | XCTAssertEqual(sut.encodedPolyline, "AA@@")
119 | }
120 |
121 | func testPrecisionShouldBeUsedProperlyInEncoding() {
122 | let coordinates = [CLLocationCoordinate2D(latitude: 10.1234567, longitude:10.1234567)]
123 |
124 | var sut = Polyline(coordinates: coordinates)
125 | XCTAssertEqual(sut.encodedPolyline, "sfx|@sfx|@")
126 |
127 | sut = Polyline(coordinates: coordinates, precision: 1e5)
128 | XCTAssertEqual(sut.encodedPolyline, "sfx|@sfx|@")
129 |
130 | sut = Polyline(coordinates: coordinates, precision: 1e6)
131 | XCTAssertEqual(sut.encodedPolyline, "ak{hRak{hR")
132 | }
133 |
134 | // MARK:- Decoding Coordinates
135 |
136 | func testEmptyPolylineShouldBeEmptyLocationArray() {
137 | let sut = Polyline(encodedPolyline: "")
138 | XCTAssertTrue(sut.coordinates != nil)
139 | XCTAssertEqual((sut.coordinates!).count, 0)
140 | }
141 |
142 | func testInvalidPolylineShouldReturnNil() {
143 | let sut = Polyline(encodedPolyline: "invalidPolylineString")
144 | XCTAssertTrue(sut.coordinates == nil)
145 | }
146 |
147 | func testValidPolylineShouldReturnValidLocationArray() {
148 | let sut = Polyline(encodedPolyline: "_p~iF~ps|U_ulLnnqC_mqNvxq`@")
149 |
150 | let coordinates = sut.coordinates!
151 |
152 | XCTAssertEqual(coordinates.count, 3)
153 | XCTAssertEqual(coordinates[0].latitude, 38.5, accuracy: COORD_EPSILON_1e5)
154 | XCTAssertEqual(coordinates[0].longitude, -120.2, accuracy: COORD_EPSILON_1e5)
155 | XCTAssertEqual(coordinates[1].latitude, 40.7, accuracy: COORD_EPSILON_1e5)
156 | XCTAssertEqual(coordinates[1].longitude, -120.95, accuracy: COORD_EPSILON_1e5)
157 | XCTAssertEqual(coordinates[2].latitude, 43.252, accuracy: COORD_EPSILON_1e5)
158 | XCTAssertEqual(coordinates[2].longitude, -126.453, accuracy: COORD_EPSILON_1e5)
159 | }
160 |
161 | func testAnotherValidPolylineShouldReturnValidLocationArray() {
162 | let sut = Polyline(encodedPolyline: "_ojiHa`tLh{IdCw{Gwc_@")
163 |
164 | let coordinates = sut.coordinates!
165 |
166 | XCTAssertEqual(coordinates.count, 3)
167 | XCTAssertEqual(coordinates[0].latitude, 48.8832, accuracy: COORD_EPSILON_1e5)
168 | XCTAssertEqual(coordinates[0].longitude, 2.23761, accuracy: COORD_EPSILON_1e5)
169 | XCTAssertEqual(coordinates[1].latitude, 48.82747, accuracy: COORD_EPSILON_1e5)
170 | XCTAssertEqual(coordinates[1].longitude, 2.23694, accuracy: COORD_EPSILON_1e5)
171 | XCTAssertEqual(coordinates[2].latitude, 48.87303, accuracy: COORD_EPSILON_1e5)
172 | XCTAssertEqual(coordinates[2].longitude, 2.40154, accuracy: COORD_EPSILON_1e5)
173 | }
174 |
175 | func testPrecisionShouldBeUsedProperlyInDecoding() {
176 |
177 | var sut = Polyline(encodedPolyline: "sfx|@sfx|@")
178 |
179 | var coordinates = sut.coordinates!
180 |
181 | XCTAssertEqual(coordinates.count, 1)
182 | XCTAssertEqual(coordinates[0].latitude, 10.1234567, accuracy: COORD_EPSILON_1e5)
183 |
184 | sut = Polyline(encodedPolyline: "sfx|@sfx|@", precision: 1e5)
185 |
186 | coordinates = sut.coordinates!
187 |
188 | XCTAssertEqual(coordinates.count, 1)
189 | XCTAssertEqual(coordinates[0].latitude, 10.1234567, accuracy: COORD_EPSILON_1e5)
190 |
191 | sut = Polyline(encodedPolyline: "ak{hRak{hR", precision: 1e6)
192 |
193 | coordinates = sut.coordinates!
194 |
195 | XCTAssertEqual(coordinates.count, 1)
196 | XCTAssertEqual(coordinates[0].latitude, 10.1234567, accuracy: COORD_EPSILON_1e6)
197 |
198 | }
199 |
200 | // MARK:- Encoding levels
201 |
202 | func testEmptylevelsShouldBeEmptyString() {
203 | let sut = Polyline(coordinates: [], levels: [])
204 |
205 | XCTAssertTrue(sut.encodedLevels != nil)
206 | XCTAssertEqual(sut.encodedLevels!, "")
207 | }
208 |
209 | func testNillevelsShouldBeNil() {
210 | let sut = Polyline(coordinates: [], levels: nil)
211 |
212 | XCTAssertTrue(sut.encodedLevels == nil)
213 | }
214 |
215 | func testValidlevelsShouldBeEncodedProperly() {
216 | let sut = Polyline(coordinates: [], levels: [0,1,2,3])
217 |
218 | XCTAssertEqual(sut.encodedLevels!, "?@AB")
219 | }
220 |
221 | // MARK:- Decoding levels
222 |
223 | func testEmptyLevelsShouldBeEmptyLevelArray() {
224 | let sut = Polyline(encodedPolyline: "", encodedLevels: "")
225 |
226 | XCTAssertTrue(sut.levels != nil,"Level array should not be nil for empty string")
227 | XCTAssertEqual((sut.levels!).count, 0)
228 | }
229 |
230 | func testInvalidLevelsShouldReturnNilLevelArray() {
231 | let sut = Polyline(encodedPolyline: "", encodedLevels: "invalidLevelString")
232 |
233 | XCTAssertTrue(sut.levels == nil, "Level array should be nil for invalid string")
234 | }
235 |
236 | func testValidLevelsShouldReturnValidLevelArray() {
237 | let sut = Polyline(encodedPolyline: "", encodedLevels: "?@AB~F")
238 |
239 | if let resultArray = sut.levels {
240 | XCTAssertEqual(resultArray.count, 5)
241 | XCTAssertEqual(resultArray[0], UInt32(0))
242 | XCTAssertEqual(resultArray[1], UInt32(1))
243 | XCTAssertEqual(resultArray[2], UInt32(2))
244 | XCTAssertEqual(resultArray[3], UInt32(3))
245 | XCTAssertEqual(resultArray[4], UInt32(255))
246 |
247 | } else {
248 | XCTFail("Valid Levels should be decoded properly")
249 | }
250 | }
251 |
252 | // MARK:- Encoding Locations
253 | func testLocationsArrayShouldBeEncodedProperly() {
254 | #if canImport(CoreLocation)
255 | let locations = [CLLocation(latitude: 0.00001, longitude: 0.00001),
256 | CLLocation(latitude: 0.00000, longitude: 0.00000)]
257 |
258 | let sut = Polyline(locations: locations)
259 | XCTAssertEqual(sut.encodedPolyline, "AA@@")
260 | #endif
261 | }
262 |
263 | // MARK:- Issues non-regression tests
264 |
265 | // Github Issue 1
266 | func testSmallNegativeDifferencesShouldBeEncodedProperly() {
267 | let coordinates = [CLLocationCoordinate2D(latitude: 37.32721043, longitude: 122.02685069),
268 | CLLocationCoordinate2D(latitude: 37.32727259, longitude: 122.02685280),
269 | CLLocationCoordinate2D(latitude: 37.32733398, longitude: 122.02684998)]
270 |
271 | let sut = Polyline(coordinates: coordinates)
272 | XCTAssertEqual(sut.encodedPolyline, "anybFyjxgVK?K?")
273 | }
274 |
275 | // Github Issue 3
276 | func testLimitValueIsProperlyEncoded() {
277 | let sourceCoordinates = [CLLocationCoordinate2D(latitude: 0.00016, longitude: -0.00032)]
278 |
279 | let sut = Polyline(coordinates: sourceCoordinates)
280 | XCTAssertEqual(sut.encodedPolyline, "_@~@")
281 | }
282 |
283 | // Github issue 4
284 | func testPrecisionIsUsedProperly() {
285 | let encoded = "}gqefAridwgFrYEAhfA{@jDsAxBoBzBaDtB{iAX{c@EsU]uf@?_WR~@tPlTFfg@?jUNj|@eBtu@K?z]cAjLkDlJuFjGyG`IyCjIsAlM?|k@v@|dArQbv@k@jIpA?"
286 | let sut : [CLLocationCoordinate2D] = decodePolyline(encoded, precision: 1e6)!
287 |
288 | XCTAssertEqual(sut.count, 30)
289 | XCTAssertEqual(sut[0].latitude, 37.332111, accuracy: COORD_EPSILON_1e6)
290 | XCTAssertEqual(sut[0].longitude, -122.030762, accuracy: COORD_EPSILON_1e6)
291 | }
292 |
293 | // Github Issue 8
294 | func testPerformances() {
295 | self.measure {
296 | 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~@")
297 | }
298 | }
299 |
300 | // MARK:- README code samples
301 |
302 | func testCoordinatesEncoding() {
303 | let coordinates = [CLLocationCoordinate2D(latitude: 40.2349727, longitude: -3.7707443),
304 | CLLocationCoordinate2D(latitude: 44.3377999, longitude: 1.2112933)]
305 |
306 | let polyline = Polyline(coordinates: coordinates)
307 | XCTAssertEqual(polyline.encodedPolyline, "qkqtFbn_Vui`Xu`l]")
308 | }
309 |
310 | func testLocationsEncoding() {
311 | #if canImport(CoreLocation)
312 | let locations = [CLLocation(latitude: 40.2349727, longitude: -3.7707443),
313 | CLLocation(latitude: 44.3377999, longitude: 1.2112933)]
314 |
315 | let polyline = Polyline(locations: locations)
316 | XCTAssertEqual(polyline.encodedPolyline, "qkqtFbn_Vui`Xu`l]")
317 | #endif
318 | }
319 |
320 | func testLevelEncoding() {
321 | let coordinates = [CLLocationCoordinate2D(latitude: 40.2349727, longitude: -3.7707443),
322 | CLLocationCoordinate2D(latitude: 44.3377999, longitude: 1.2112933)]
323 |
324 | let levels: [UInt32] = [0,1,2,255]
325 |
326 | let polyline = Polyline(coordinates: coordinates, levels: levels)
327 | let _ : String? = polyline.encodedLevels
328 | }
329 |
330 | func testPolylineDecodingToCoordinate() {
331 | let polyline = Polyline(encodedPolyline: "qkqtFbn_Vui`Xu`l]")
332 |
333 | let decodedCoordinates: [CLLocationCoordinate2D]? = polyline.coordinates
334 | XCTAssertEqual(2, decodedCoordinates!.count)
335 | }
336 |
337 | func testPolylineDecodingToLocations() {
338 | #if canImport(CoreLocation)
339 | let polyline = Polyline(encodedPolyline: "qkqtFbn_Vui`Xu`l]")
340 | let decodedLocations: [CLLocation]? = polyline.locations
341 |
342 | XCTAssertEqual(2, decodedLocations!.count)
343 | #endif
344 | }
345 |
346 | func testLevelDecoding() {
347 | let polyline = Polyline(encodedPolyline: "qkqtFbn_Vui`Xu`l]", encodedLevels: "BA")
348 | let decodedLevels: [UInt32]? = polyline.levels
349 |
350 | XCTAssertEqual(2, decodedLevels!.count)
351 | }
352 |
353 | func testPrecision() {
354 | // OSRM uses a 6 digit precision
355 | let _ = Polyline(encodedPolyline: "ak{hRak{hR", precision: 1e6)
356 | }
357 |
358 | #if canImport(MapKit)
359 | @available(tvOS 9.2, *)
360 | func testPolylineConvertionToMKPolyline() {
361 | let polyline = Polyline(encodedPolyline: "qkqtFbn_Vui`Xu`l]")
362 |
363 | let mkPolyline = polyline.mkPolyline
364 | XCTAssertNotNil(mkPolyline)
365 | XCTAssertTrue(polyline.coordinates?.count == mkPolyline?.pointCount)
366 | }
367 | #endif
368 |
369 | #if canImport(MapKit)
370 | @available(tvOS 9.2, *)
371 | func testPolylineConvertionToMKPolylineWhenEncodingFailed() {
372 | let polyline = Polyline(encodedPolyline: "invalidPolylineString")
373 | let mkPolyline = polyline.mkPolyline
374 | XCTAssertNil(mkPolyline)
375 | }
376 | #endif
377 |
378 | #if canImport(MapKit)
379 | @available(tvOS 9.2, *)
380 | func testEmptyPolylineConvertionShouldBeEmptyMKPolyline() {
381 | let polyline = Polyline(encodedPolyline: "")
382 | let mkPolyline = polyline.mkPolyline
383 | XCTAssertTrue(mkPolyline?.pointCount == 0)
384 | }
385 | #endif
386 | }
387 |
--------------------------------------------------------------------------------
/Polyline.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 207F640419B5DF7E005261FA /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 207F640319B5DF7E005261FA /* Polyline.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 207F640E19B5DF7E005261FA /* PolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207F640D19B5DF7E005261FA /* PolylineTests.swift */; };
12 | 207F641B19B5E10C005261FA /* Polyline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207F641A19B5E10C005261FA /* Polyline.swift */; };
13 | 28DD887E1AA1280C001CC005 /* FunctionalPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DD887D1AA1280C001CC005 /* FunctionalPolylineTests.swift */; };
14 | 64E1F8751A285A76002F25D3 /* Polyline.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 207F63FE19B5DF7E005261FA /* Polyline.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
15 | 91F783361CE4EB7F004E87E3 /* Polyline.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 91F7832C1CE4EB7E004E87E3 /* Polyline.framework */; };
16 | DA01FB6F255361EF00335C7C /* CoreLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA01FB6E255361EF00335C7C /* CoreLocation.swift */; };
17 | DA01FB70255361EF00335C7C /* CoreLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA01FB6E255361EF00335C7C /* CoreLocation.swift */; };
18 | DA01FB71255361EF00335C7C /* CoreLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA01FB6E255361EF00335C7C /* CoreLocation.swift */; };
19 | DA01FB72255361EF00335C7C /* CoreLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA01FB6E255361EF00335C7C /* CoreLocation.swift */; };
20 | DA1A10661D003CF9009F82FA /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 207F640319B5DF7E005261FA /* Polyline.h */; settings = {ATTRIBUTES = (Public, ); }; };
21 | DA1A10691D003DFB009F82FA /* Polyline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207F641A19B5E10C005261FA /* Polyline.swift */; };
22 | DA1A106A1D003E56009F82FA /* PolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207F640D19B5DF7E005261FA /* PolylineTests.swift */; };
23 | DA1A106B1D003E56009F82FA /* FunctionalPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DD887D1AA1280C001CC005 /* FunctionalPolylineTests.swift */; };
24 | DA1A107B1D003E88009F82FA /* Polyline.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA1A10711D003E88009F82FA /* Polyline.framework */; };
25 | DA1A10881D003EA6009F82FA /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 207F640319B5DF7E005261FA /* Polyline.h */; settings = {ATTRIBUTES = (Public, ); }; };
26 | DA1A10891D003EA6009F82FA /* Polyline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207F641A19B5E10C005261FA /* Polyline.swift */; };
27 | DA1A108A1D003EBB009F82FA /* PolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207F640D19B5DF7E005261FA /* PolylineTests.swift */; };
28 | DA1A108B1D003EBB009F82FA /* FunctionalPolylineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DD887D1AA1280C001CC005 /* FunctionalPolylineTests.swift */; };
29 | DA1A10991D004035009F82FA /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = 207F640319B5DF7E005261FA /* Polyline.h */; settings = {ATTRIBUTES = (Public, ); }; };
30 | DA1A109A1D004035009F82FA /* Polyline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 207F641A19B5E10C005261FA /* Polyline.swift */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXContainerItemProxy section */
34 | 91F783371CE4EB7F004E87E3 /* PBXContainerItemProxy */ = {
35 | isa = PBXContainerItemProxy;
36 | containerPortal = 207F63F519B5DF7E005261FA /* Project object */;
37 | proxyType = 1;
38 | remoteGlobalIDString = 91F7832B1CE4EB7E004E87E3;
39 | remoteInfo = PolylineMac;
40 | };
41 | DA1A107C1D003E88009F82FA /* PBXContainerItemProxy */ = {
42 | isa = PBXContainerItemProxy;
43 | containerPortal = 207F63F519B5DF7E005261FA /* Project object */;
44 | proxyType = 1;
45 | remoteGlobalIDString = DA1A10701D003E88009F82FA;
46 | remoteInfo = PolylineTV;
47 | };
48 | /* End PBXContainerItemProxy section */
49 |
50 | /* Begin PBXCopyFilesBuildPhase section */
51 | 64E1F8741A285A66002F25D3 /* Copy Frameworks */ = {
52 | isa = PBXCopyFilesBuildPhase;
53 | buildActionMask = 2147483647;
54 | dstPath = "";
55 | dstSubfolderSpec = 10;
56 | files = (
57 | 64E1F8751A285A76002F25D3 /* Polyline.framework in Copy Frameworks */,
58 | );
59 | name = "Copy Frameworks";
60 | runOnlyForDeploymentPostprocessing = 0;
61 | };
62 | /* End PBXCopyFilesBuildPhase section */
63 |
64 | /* Begin PBXFileReference section */
65 | 207F63FE19B5DF7E005261FA /* Polyline.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Polyline.framework; sourceTree = BUILT_PRODUCTS_DIR; };
66 | 207F640219B5DF7E005261FA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
67 | 207F640319B5DF7E005261FA /* Polyline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Polyline.h; sourceTree = ""; };
68 | 207F640919B5DF7E005261FA /* PolylineTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PolylineTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
69 | 207F640C19B5DF7E005261FA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
70 | 207F640D19B5DF7E005261FA /* PolylineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineTests.swift; sourceTree = ""; };
71 | 207F641819B5E05A005261FA /* LICENSE.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; };
72 | 207F641A19B5E10C005261FA /* Polyline.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Polyline.swift; sourceTree = ""; };
73 | 207F641C19B5EDC3005261FA /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
74 | 28DD887D1AA1280C001CC005 /* FunctionalPolylineTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FunctionalPolylineTests.swift; sourceTree = ""; };
75 | 91F7832C1CE4EB7E004E87E3 /* Polyline.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Polyline.framework; sourceTree = BUILT_PRODUCTS_DIR; };
76 | 91F783351CE4EB7E004E87E3 /* PolylineTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PolylineTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
77 | DA01FB6E255361EF00335C7C /* CoreLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreLocation.swift; sourceTree = ""; };
78 | DA1A10711D003E88009F82FA /* Polyline.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Polyline.framework; sourceTree = BUILT_PRODUCTS_DIR; };
79 | DA1A107A1D003E88009F82FA /* PolylineTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PolylineTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
80 | DA1A10911D00400D009F82FA /* Polyline.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Polyline.framework; sourceTree = BUILT_PRODUCTS_DIR; };
81 | /* End PBXFileReference section */
82 |
83 | /* Begin PBXFrameworksBuildPhase section */
84 | 207F63FA19B5DF7E005261FA /* Frameworks */ = {
85 | isa = PBXFrameworksBuildPhase;
86 | buildActionMask = 2147483647;
87 | files = (
88 | );
89 | runOnlyForDeploymentPostprocessing = 0;
90 | };
91 | 207F640619B5DF7E005261FA /* Frameworks */ = {
92 | isa = PBXFrameworksBuildPhase;
93 | buildActionMask = 2147483647;
94 | files = (
95 | );
96 | runOnlyForDeploymentPostprocessing = 0;
97 | };
98 | 91F783281CE4EB7E004E87E3 /* Frameworks */ = {
99 | isa = PBXFrameworksBuildPhase;
100 | buildActionMask = 2147483647;
101 | files = (
102 | );
103 | runOnlyForDeploymentPostprocessing = 0;
104 | };
105 | 91F783321CE4EB7E004E87E3 /* Frameworks */ = {
106 | isa = PBXFrameworksBuildPhase;
107 | buildActionMask = 2147483647;
108 | files = (
109 | 91F783361CE4EB7F004E87E3 /* Polyline.framework in Frameworks */,
110 | );
111 | runOnlyForDeploymentPostprocessing = 0;
112 | };
113 | DA1A106D1D003E88009F82FA /* Frameworks */ = {
114 | isa = PBXFrameworksBuildPhase;
115 | buildActionMask = 2147483647;
116 | files = (
117 | );
118 | runOnlyForDeploymentPostprocessing = 0;
119 | };
120 | DA1A10771D003E88009F82FA /* Frameworks */ = {
121 | isa = PBXFrameworksBuildPhase;
122 | buildActionMask = 2147483647;
123 | files = (
124 | DA1A107B1D003E88009F82FA /* Polyline.framework in Frameworks */,
125 | );
126 | runOnlyForDeploymentPostprocessing = 0;
127 | };
128 | DA1A108D1D00400D009F82FA /* Frameworks */ = {
129 | isa = PBXFrameworksBuildPhase;
130 | buildActionMask = 2147483647;
131 | files = (
132 | );
133 | runOnlyForDeploymentPostprocessing = 0;
134 | };
135 | /* End PBXFrameworksBuildPhase section */
136 |
137 | /* Begin PBXGroup section */
138 | 207F63F419B5DF7E005261FA = {
139 | isa = PBXGroup;
140 | children = (
141 | 35A28A5720E284B20030D1D9 /* Tests */,
142 | 35A28A5420E283D10030D1D9 /* Sources */,
143 | 207F641C19B5EDC3005261FA /* README.md */,
144 | 207F641819B5E05A005261FA /* LICENSE.txt */,
145 | 207F63FF19B5DF7E005261FA /* Products */,
146 | );
147 | sourceTree = "";
148 | };
149 | 207F63FF19B5DF7E005261FA /* Products */ = {
150 | isa = PBXGroup;
151 | children = (
152 | 207F63FE19B5DF7E005261FA /* Polyline.framework */,
153 | 207F640919B5DF7E005261FA /* PolylineTests.xctest */,
154 | 91F7832C1CE4EB7E004E87E3 /* Polyline.framework */,
155 | 91F783351CE4EB7E004E87E3 /* PolylineTests.xctest */,
156 | DA1A10711D003E88009F82FA /* Polyline.framework */,
157 | DA1A107A1D003E88009F82FA /* PolylineTests.xctest */,
158 | DA1A10911D00400D009F82FA /* Polyline.framework */,
159 | );
160 | name = Products;
161 | sourceTree = "";
162 | };
163 | 207F640A19B5DF7E005261FA /* PolylineTests */ = {
164 | isa = PBXGroup;
165 | children = (
166 | 207F640D19B5DF7E005261FA /* PolylineTests.swift */,
167 | 28DD887D1AA1280C001CC005 /* FunctionalPolylineTests.swift */,
168 | 207F640B19B5DF7E005261FA /* Supporting Files */,
169 | );
170 | path = PolylineTests;
171 | sourceTree = "";
172 | };
173 | 207F640B19B5DF7E005261FA /* Supporting Files */ = {
174 | isa = PBXGroup;
175 | children = (
176 | 207F640C19B5DF7E005261FA /* Info.plist */,
177 | );
178 | name = "Supporting Files";
179 | sourceTree = "";
180 | };
181 | 35A28A5420E283D10030D1D9 /* Sources */ = {
182 | isa = PBXGroup;
183 | children = (
184 | 35A28A5520E283EA0030D1D9 /* Polyline */,
185 | );
186 | path = Sources;
187 | sourceTree = "";
188 | };
189 | 35A28A5520E283EA0030D1D9 /* Polyline */ = {
190 | isa = PBXGroup;
191 | children = (
192 | 207F640319B5DF7E005261FA /* Polyline.h */,
193 | 207F641A19B5E10C005261FA /* Polyline.swift */,
194 | DA01FB6E255361EF00335C7C /* CoreLocation.swift */,
195 | 35A28A5620E283F90030D1D9 /* Supporting Files */,
196 | );
197 | path = Polyline;
198 | sourceTree = "";
199 | };
200 | 35A28A5620E283F90030D1D9 /* Supporting Files */ = {
201 | isa = PBXGroup;
202 | children = (
203 | 207F640219B5DF7E005261FA /* Info.plist */,
204 | );
205 | name = "Supporting Files";
206 | sourceTree = "";
207 | };
208 | 35A28A5720E284B20030D1D9 /* Tests */ = {
209 | isa = PBXGroup;
210 | children = (
211 | 207F640A19B5DF7E005261FA /* PolylineTests */,
212 | );
213 | path = Tests;
214 | sourceTree = "";
215 | };
216 | /* End PBXGroup section */
217 |
218 | /* Begin PBXHeadersBuildPhase section */
219 | 207F63FB19B5DF7E005261FA /* Headers */ = {
220 | isa = PBXHeadersBuildPhase;
221 | buildActionMask = 2147483647;
222 | files = (
223 | 207F640419B5DF7E005261FA /* Polyline.h in Headers */,
224 | );
225 | runOnlyForDeploymentPostprocessing = 0;
226 | };
227 | 91F783291CE4EB7E004E87E3 /* Headers */ = {
228 | isa = PBXHeadersBuildPhase;
229 | buildActionMask = 2147483647;
230 | files = (
231 | DA1A10661D003CF9009F82FA /* Polyline.h in Headers */,
232 | );
233 | runOnlyForDeploymentPostprocessing = 0;
234 | };
235 | DA1A106E1D003E88009F82FA /* Headers */ = {
236 | isa = PBXHeadersBuildPhase;
237 | buildActionMask = 2147483647;
238 | files = (
239 | DA1A10881D003EA6009F82FA /* Polyline.h in Headers */,
240 | );
241 | runOnlyForDeploymentPostprocessing = 0;
242 | };
243 | DA1A108E1D00400D009F82FA /* Headers */ = {
244 | isa = PBXHeadersBuildPhase;
245 | buildActionMask = 2147483647;
246 | files = (
247 | DA1A10991D004035009F82FA /* Polyline.h in Headers */,
248 | );
249 | runOnlyForDeploymentPostprocessing = 0;
250 | };
251 | /* End PBXHeadersBuildPhase section */
252 |
253 | /* Begin PBXNativeTarget section */
254 | 207F63FD19B5DF7E005261FA /* Polyline */ = {
255 | isa = PBXNativeTarget;
256 | buildConfigurationList = 207F641119B5DF7E005261FA /* Build configuration list for PBXNativeTarget "Polyline" */;
257 | buildPhases = (
258 | 207F63F919B5DF7E005261FA /* Sources */,
259 | 207F63FA19B5DF7E005261FA /* Frameworks */,
260 | 207F63FB19B5DF7E005261FA /* Headers */,
261 | 207F63FC19B5DF7E005261FA /* Resources */,
262 | );
263 | buildRules = (
264 | );
265 | dependencies = (
266 | );
267 | name = Polyline;
268 | productName = Polyline;
269 | productReference = 207F63FE19B5DF7E005261FA /* Polyline.framework */;
270 | productType = "com.apple.product-type.framework";
271 | };
272 | 207F640819B5DF7E005261FA /* PolylineTests */ = {
273 | isa = PBXNativeTarget;
274 | buildConfigurationList = 207F641419B5DF7E005261FA /* Build configuration list for PBXNativeTarget "PolylineTests" */;
275 | buildPhases = (
276 | 207F640519B5DF7E005261FA /* Sources */,
277 | 207F640619B5DF7E005261FA /* Frameworks */,
278 | 207F640719B5DF7E005261FA /* Resources */,
279 | 64E1F8741A285A66002F25D3 /* Copy Frameworks */,
280 | );
281 | buildRules = (
282 | );
283 | dependencies = (
284 | );
285 | name = PolylineTests;
286 | productName = PolylineTests;
287 | productReference = 207F640919B5DF7E005261FA /* PolylineTests.xctest */;
288 | productType = "com.apple.product-type.bundle.unit-test";
289 | };
290 | 91F7832B1CE4EB7E004E87E3 /* PolylineMac */ = {
291 | isa = PBXNativeTarget;
292 | buildConfigurationList = 91F7833D1CE4EB7F004E87E3 /* Build configuration list for PBXNativeTarget "PolylineMac" */;
293 | buildPhases = (
294 | 91F783271CE4EB7E004E87E3 /* Sources */,
295 | 91F783281CE4EB7E004E87E3 /* Frameworks */,
296 | 91F783291CE4EB7E004E87E3 /* Headers */,
297 | 91F7832A1CE4EB7E004E87E3 /* Resources */,
298 | );
299 | buildRules = (
300 | );
301 | dependencies = (
302 | );
303 | name = PolylineMac;
304 | productName = PolylineMac;
305 | productReference = 91F7832C1CE4EB7E004E87E3 /* Polyline.framework */;
306 | productType = "com.apple.product-type.framework";
307 | };
308 | 91F783341CE4EB7E004E87E3 /* PolylineMacTests */ = {
309 | isa = PBXNativeTarget;
310 | buildConfigurationList = 91F783401CE4EB7F004E87E3 /* Build configuration list for PBXNativeTarget "PolylineMacTests" */;
311 | buildPhases = (
312 | 91F783311CE4EB7E004E87E3 /* Sources */,
313 | 91F783321CE4EB7E004E87E3 /* Frameworks */,
314 | 91F783331CE4EB7E004E87E3 /* Resources */,
315 | );
316 | buildRules = (
317 | );
318 | dependencies = (
319 | 91F783381CE4EB7F004E87E3 /* PBXTargetDependency */,
320 | );
321 | name = PolylineMacTests;
322 | productName = PolylineMacTests;
323 | productReference = 91F783351CE4EB7E004E87E3 /* PolylineTests.xctest */;
324 | productType = "com.apple.product-type.bundle.unit-test";
325 | };
326 | DA1A10701D003E88009F82FA /* PolylineTV */ = {
327 | isa = PBXNativeTarget;
328 | buildConfigurationList = DA1A10861D003E88009F82FA /* Build configuration list for PBXNativeTarget "PolylineTV" */;
329 | buildPhases = (
330 | DA1A106C1D003E88009F82FA /* Sources */,
331 | DA1A106D1D003E88009F82FA /* Frameworks */,
332 | DA1A106E1D003E88009F82FA /* Headers */,
333 | DA1A106F1D003E88009F82FA /* Resources */,
334 | );
335 | buildRules = (
336 | );
337 | dependencies = (
338 | );
339 | name = PolylineTV;
340 | productName = PolylineTV;
341 | productReference = DA1A10711D003E88009F82FA /* Polyline.framework */;
342 | productType = "com.apple.product-type.framework";
343 | };
344 | DA1A10791D003E88009F82FA /* PolylineTVTests */ = {
345 | isa = PBXNativeTarget;
346 | buildConfigurationList = DA1A10871D003E88009F82FA /* Build configuration list for PBXNativeTarget "PolylineTVTests" */;
347 | buildPhases = (
348 | DA1A10761D003E88009F82FA /* Sources */,
349 | DA1A10771D003E88009F82FA /* Frameworks */,
350 | DA1A10781D003E88009F82FA /* Resources */,
351 | );
352 | buildRules = (
353 | );
354 | dependencies = (
355 | DA1A107D1D003E88009F82FA /* PBXTargetDependency */,
356 | );
357 | name = PolylineTVTests;
358 | productName = PolylineTVTests;
359 | productReference = DA1A107A1D003E88009F82FA /* PolylineTests.xctest */;
360 | productType = "com.apple.product-type.bundle.unit-test";
361 | };
362 | DA1A10901D00400D009F82FA /* PolylineWatch */ = {
363 | isa = PBXNativeTarget;
364 | buildConfigurationList = DA1A10961D00400D009F82FA /* Build configuration list for PBXNativeTarget "PolylineWatch" */;
365 | buildPhases = (
366 | DA1A108C1D00400D009F82FA /* Sources */,
367 | DA1A108D1D00400D009F82FA /* Frameworks */,
368 | DA1A108E1D00400D009F82FA /* Headers */,
369 | DA1A108F1D00400D009F82FA /* Resources */,
370 | );
371 | buildRules = (
372 | );
373 | dependencies = (
374 | );
375 | name = PolylineWatch;
376 | productName = PolylineWatch;
377 | productReference = DA1A10911D00400D009F82FA /* Polyline.framework */;
378 | productType = "com.apple.product-type.framework";
379 | };
380 | /* End PBXNativeTarget section */
381 |
382 | /* Begin PBXProject section */
383 | 207F63F519B5DF7E005261FA /* Project object */ = {
384 | isa = PBXProject;
385 | attributes = {
386 | LastSwiftMigration = 0700;
387 | LastSwiftUpdateCheck = 0730;
388 | LastUpgradeCheck = 1400;
389 | ORGANIZATIONNAME = "Raphael MOR";
390 | TargetAttributes = {
391 | 207F63FD19B5DF7E005261FA = {
392 | CreatedOnToolsVersion = 6.0;
393 | LastSwiftMigration = 0900;
394 | };
395 | 207F640819B5DF7E005261FA = {
396 | CreatedOnToolsVersion = 6.0;
397 | LastSwiftMigration = 0900;
398 | };
399 | 91F7832B1CE4EB7E004E87E3 = {
400 | CreatedOnToolsVersion = 7.3.1;
401 | LastSwiftMigration = 1130;
402 | };
403 | 91F783341CE4EB7E004E87E3 = {
404 | CreatedOnToolsVersion = 7.3.1;
405 | LastSwiftMigration = 1130;
406 | };
407 | DA1A10701D003E88009F82FA = {
408 | CreatedOnToolsVersion = 7.3.1;
409 | };
410 | DA1A10791D003E88009F82FA = {
411 | CreatedOnToolsVersion = 7.3.1;
412 | };
413 | DA1A10901D00400D009F82FA = {
414 | CreatedOnToolsVersion = 7.3.1;
415 | LastSwiftMigration = 0800;
416 | };
417 | };
418 | };
419 | buildConfigurationList = 207F63F819B5DF7E005261FA /* Build configuration list for PBXProject "Polyline" */;
420 | compatibilityVersion = "Xcode 3.2";
421 | developmentRegion = en;
422 | hasScannedForEncodings = 0;
423 | knownRegions = (
424 | en,
425 | Base,
426 | );
427 | mainGroup = 207F63F419B5DF7E005261FA;
428 | productRefGroup = 207F63FF19B5DF7E005261FA /* Products */;
429 | projectDirPath = "";
430 | projectRoot = "";
431 | targets = (
432 | 207F63FD19B5DF7E005261FA /* Polyline */,
433 | 207F640819B5DF7E005261FA /* PolylineTests */,
434 | 91F7832B1CE4EB7E004E87E3 /* PolylineMac */,
435 | 91F783341CE4EB7E004E87E3 /* PolylineMacTests */,
436 | DA1A10701D003E88009F82FA /* PolylineTV */,
437 | DA1A10791D003E88009F82FA /* PolylineTVTests */,
438 | DA1A10901D00400D009F82FA /* PolylineWatch */,
439 | );
440 | };
441 | /* End PBXProject section */
442 |
443 | /* Begin PBXResourcesBuildPhase section */
444 | 207F63FC19B5DF7E005261FA /* Resources */ = {
445 | isa = PBXResourcesBuildPhase;
446 | buildActionMask = 2147483647;
447 | files = (
448 | );
449 | runOnlyForDeploymentPostprocessing = 0;
450 | };
451 | 207F640719B5DF7E005261FA /* Resources */ = {
452 | isa = PBXResourcesBuildPhase;
453 | buildActionMask = 2147483647;
454 | files = (
455 | );
456 | runOnlyForDeploymentPostprocessing = 0;
457 | };
458 | 91F7832A1CE4EB7E004E87E3 /* Resources */ = {
459 | isa = PBXResourcesBuildPhase;
460 | buildActionMask = 2147483647;
461 | files = (
462 | );
463 | runOnlyForDeploymentPostprocessing = 0;
464 | };
465 | 91F783331CE4EB7E004E87E3 /* Resources */ = {
466 | isa = PBXResourcesBuildPhase;
467 | buildActionMask = 2147483647;
468 | files = (
469 | );
470 | runOnlyForDeploymentPostprocessing = 0;
471 | };
472 | DA1A106F1D003E88009F82FA /* Resources */ = {
473 | isa = PBXResourcesBuildPhase;
474 | buildActionMask = 2147483647;
475 | files = (
476 | );
477 | runOnlyForDeploymentPostprocessing = 0;
478 | };
479 | DA1A10781D003E88009F82FA /* Resources */ = {
480 | isa = PBXResourcesBuildPhase;
481 | buildActionMask = 2147483647;
482 | files = (
483 | );
484 | runOnlyForDeploymentPostprocessing = 0;
485 | };
486 | DA1A108F1D00400D009F82FA /* Resources */ = {
487 | isa = PBXResourcesBuildPhase;
488 | buildActionMask = 2147483647;
489 | files = (
490 | );
491 | runOnlyForDeploymentPostprocessing = 0;
492 | };
493 | /* End PBXResourcesBuildPhase section */
494 |
495 | /* Begin PBXSourcesBuildPhase section */
496 | 207F63F919B5DF7E005261FA /* Sources */ = {
497 | isa = PBXSourcesBuildPhase;
498 | buildActionMask = 2147483647;
499 | files = (
500 | 207F641B19B5E10C005261FA /* Polyline.swift in Sources */,
501 | DA01FB6F255361EF00335C7C /* CoreLocation.swift in Sources */,
502 | );
503 | runOnlyForDeploymentPostprocessing = 0;
504 | };
505 | 207F640519B5DF7E005261FA /* Sources */ = {
506 | isa = PBXSourcesBuildPhase;
507 | buildActionMask = 2147483647;
508 | files = (
509 | 28DD887E1AA1280C001CC005 /* FunctionalPolylineTests.swift in Sources */,
510 | 207F640E19B5DF7E005261FA /* PolylineTests.swift in Sources */,
511 | );
512 | runOnlyForDeploymentPostprocessing = 0;
513 | };
514 | 91F783271CE4EB7E004E87E3 /* Sources */ = {
515 | isa = PBXSourcesBuildPhase;
516 | buildActionMask = 2147483647;
517 | files = (
518 | DA1A10691D003DFB009F82FA /* Polyline.swift in Sources */,
519 | DA01FB70255361EF00335C7C /* CoreLocation.swift in Sources */,
520 | );
521 | runOnlyForDeploymentPostprocessing = 0;
522 | };
523 | 91F783311CE4EB7E004E87E3 /* Sources */ = {
524 | isa = PBXSourcesBuildPhase;
525 | buildActionMask = 2147483647;
526 | files = (
527 | DA1A106B1D003E56009F82FA /* FunctionalPolylineTests.swift in Sources */,
528 | DA1A106A1D003E56009F82FA /* PolylineTests.swift in Sources */,
529 | );
530 | runOnlyForDeploymentPostprocessing = 0;
531 | };
532 | DA1A106C1D003E88009F82FA /* Sources */ = {
533 | isa = PBXSourcesBuildPhase;
534 | buildActionMask = 2147483647;
535 | files = (
536 | DA1A10891D003EA6009F82FA /* Polyline.swift in Sources */,
537 | DA01FB71255361EF00335C7C /* CoreLocation.swift in Sources */,
538 | );
539 | runOnlyForDeploymentPostprocessing = 0;
540 | };
541 | DA1A10761D003E88009F82FA /* Sources */ = {
542 | isa = PBXSourcesBuildPhase;
543 | buildActionMask = 2147483647;
544 | files = (
545 | DA1A108B1D003EBB009F82FA /* FunctionalPolylineTests.swift in Sources */,
546 | DA1A108A1D003EBB009F82FA /* PolylineTests.swift in Sources */,
547 | );
548 | runOnlyForDeploymentPostprocessing = 0;
549 | };
550 | DA1A108C1D00400D009F82FA /* Sources */ = {
551 | isa = PBXSourcesBuildPhase;
552 | buildActionMask = 2147483647;
553 | files = (
554 | DA1A109A1D004035009F82FA /* Polyline.swift in Sources */,
555 | DA01FB72255361EF00335C7C /* CoreLocation.swift in Sources */,
556 | );
557 | runOnlyForDeploymentPostprocessing = 0;
558 | };
559 | /* End PBXSourcesBuildPhase section */
560 |
561 | /* Begin PBXTargetDependency section */
562 | 91F783381CE4EB7F004E87E3 /* PBXTargetDependency */ = {
563 | isa = PBXTargetDependency;
564 | target = 91F7832B1CE4EB7E004E87E3 /* PolylineMac */;
565 | targetProxy = 91F783371CE4EB7F004E87E3 /* PBXContainerItemProxy */;
566 | };
567 | DA1A107D1D003E88009F82FA /* PBXTargetDependency */ = {
568 | isa = PBXTargetDependency;
569 | target = DA1A10701D003E88009F82FA /* PolylineTV */;
570 | targetProxy = DA1A107C1D003E88009F82FA /* PBXContainerItemProxy */;
571 | };
572 | /* End PBXTargetDependency section */
573 |
574 | /* Begin XCBuildConfiguration section */
575 | 207F640F19B5DF7E005261FA /* Debug */ = {
576 | isa = XCBuildConfiguration;
577 | buildSettings = {
578 | ALWAYS_SEARCH_USER_PATHS = NO;
579 | BITCODE_GENERATION_MODE = bitcode;
580 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
581 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
582 | CLANG_CXX_LIBRARY = "libc++";
583 | CLANG_ENABLE_MODULES = YES;
584 | CLANG_ENABLE_OBJC_ARC = YES;
585 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
586 | CLANG_WARN_BOOL_CONVERSION = YES;
587 | CLANG_WARN_COMMA = YES;
588 | CLANG_WARN_CONSTANT_CONVERSION = YES;
589 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
590 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
591 | CLANG_WARN_EMPTY_BODY = YES;
592 | CLANG_WARN_ENUM_CONVERSION = YES;
593 | CLANG_WARN_INFINITE_RECURSION = YES;
594 | CLANG_WARN_INT_CONVERSION = YES;
595 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
596 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
597 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
598 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
599 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
600 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
601 | CLANG_WARN_STRICT_PROTOTYPES = YES;
602 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
603 | CLANG_WARN_UNREACHABLE_CODE = YES;
604 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
605 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
606 | COPY_PHASE_STRIP = NO;
607 | CURRENT_PROJECT_VERSION = 6;
608 | ENABLE_STRICT_OBJC_MSGSEND = YES;
609 | ENABLE_TESTABILITY = YES;
610 | GCC_C_LANGUAGE_STANDARD = gnu99;
611 | GCC_DYNAMIC_NO_PIC = NO;
612 | GCC_NO_COMMON_BLOCKS = YES;
613 | GCC_OPTIMIZATION_LEVEL = 0;
614 | GCC_PREPROCESSOR_DEFINITIONS = (
615 | "DEBUG=1",
616 | "$(inherited)",
617 | );
618 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
619 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
620 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
621 | GCC_WARN_UNDECLARED_SELECTOR = YES;
622 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
623 | GCC_WARN_UNUSED_FUNCTION = YES;
624 | GCC_WARN_UNUSED_VARIABLE = YES;
625 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
626 | MACOSX_DEPLOYMENT_TARGET = 10.14;
627 | MTL_ENABLE_DEBUG_INFO = YES;
628 | ONLY_ACTIVE_ARCH = YES;
629 | SDKROOT = iphoneos;
630 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
631 | SWIFT_VERSION = 5.0;
632 | TARGETED_DEVICE_FAMILY = "1,2";
633 | TVOS_DEPLOYMENT_TARGET = 12.0;
634 | VERSIONING_SYSTEM = "apple-generic";
635 | VERSION_INFO_PREFIX = "";
636 | WATCHOS_DEPLOYMENT_TARGET = 5.0;
637 | };
638 | name = Debug;
639 | };
640 | 207F641019B5DF7E005261FA /* Release */ = {
641 | isa = XCBuildConfiguration;
642 | buildSettings = {
643 | ALWAYS_SEARCH_USER_PATHS = NO;
644 | BITCODE_GENERATION_MODE = bitcode;
645 | BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
646 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
647 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
648 | CLANG_CXX_LIBRARY = "libc++";
649 | CLANG_ENABLE_MODULES = YES;
650 | CLANG_ENABLE_OBJC_ARC = YES;
651 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
652 | CLANG_WARN_BOOL_CONVERSION = YES;
653 | CLANG_WARN_COMMA = YES;
654 | CLANG_WARN_CONSTANT_CONVERSION = YES;
655 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
656 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
657 | CLANG_WARN_EMPTY_BODY = YES;
658 | CLANG_WARN_ENUM_CONVERSION = YES;
659 | CLANG_WARN_INFINITE_RECURSION = YES;
660 | CLANG_WARN_INT_CONVERSION = YES;
661 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
662 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
663 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
664 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
665 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
666 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
667 | CLANG_WARN_STRICT_PROTOTYPES = YES;
668 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
669 | CLANG_WARN_UNREACHABLE_CODE = YES;
670 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
671 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
672 | COPY_PHASE_STRIP = YES;
673 | CURRENT_PROJECT_VERSION = 6;
674 | ENABLE_NS_ASSERTIONS = NO;
675 | ENABLE_STRICT_OBJC_MSGSEND = YES;
676 | GCC_C_LANGUAGE_STANDARD = gnu99;
677 | GCC_NO_COMMON_BLOCKS = YES;
678 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
679 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
680 | GCC_WARN_UNDECLARED_SELECTOR = YES;
681 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
682 | GCC_WARN_UNUSED_FUNCTION = YES;
683 | GCC_WARN_UNUSED_VARIABLE = YES;
684 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
685 | MACOSX_DEPLOYMENT_TARGET = 10.14;
686 | MTL_ENABLE_DEBUG_INFO = NO;
687 | SDKROOT = iphoneos;
688 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
689 | SWIFT_VERSION = 5.0;
690 | TARGETED_DEVICE_FAMILY = "1,2";
691 | TVOS_DEPLOYMENT_TARGET = 12.0;
692 | VALIDATE_PRODUCT = YES;
693 | VERSIONING_SYSTEM = "apple-generic";
694 | VERSION_INFO_PREFIX = "";
695 | WATCHOS_DEPLOYMENT_TARGET = 5.0;
696 | };
697 | name = Release;
698 | };
699 | 207F641219B5DF7E005261FA /* Debug */ = {
700 | isa = XCBuildConfiguration;
701 | buildSettings = {
702 | APPLICATION_EXTENSION_API_ONLY = YES;
703 | CLANG_ENABLE_MODULES = YES;
704 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
705 | DEFINES_MODULE = YES;
706 | DYLIB_COMPATIBILITY_VERSION = 1;
707 | DYLIB_CURRENT_VERSION = 7;
708 | DYLIB_INSTALL_NAME_BASE = "@rpath";
709 | EXCLUDED_ARCHS = "";
710 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
711 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
712 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
713 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
714 | PRODUCT_BUNDLE_IDENTIFIER = "com.ramoapps.$(PRODUCT_NAME:rfc1034identifier)";
715 | PRODUCT_NAME = "$(TARGET_NAME)";
716 | SKIP_INSTALL = YES;
717 | SWIFT_OBJC_BRIDGING_HEADER = "";
718 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
719 | };
720 | name = Debug;
721 | };
722 | 207F641319B5DF7E005261FA /* Release */ = {
723 | isa = XCBuildConfiguration;
724 | buildSettings = {
725 | APPLICATION_EXTENSION_API_ONLY = YES;
726 | CLANG_ENABLE_MODULES = YES;
727 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
728 | DEFINES_MODULE = YES;
729 | DYLIB_COMPATIBILITY_VERSION = 1;
730 | DYLIB_CURRENT_VERSION = 7;
731 | DYLIB_INSTALL_NAME_BASE = "@rpath";
732 | EXCLUDED_ARCHS = "";
733 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
734 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
735 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
736 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
737 | PRODUCT_BUNDLE_IDENTIFIER = "com.ramoapps.$(PRODUCT_NAME:rfc1034identifier)";
738 | PRODUCT_NAME = "$(TARGET_NAME)";
739 | SKIP_INSTALL = YES;
740 | SWIFT_OBJC_BRIDGING_HEADER = "";
741 | };
742 | name = Release;
743 | };
744 | 207F641519B5DF7E005261FA /* Debug */ = {
745 | isa = XCBuildConfiguration;
746 | buildSettings = {
747 | GCC_PREPROCESSOR_DEFINITIONS = (
748 | "DEBUG=1",
749 | "$(inherited)",
750 | );
751 | INFOPLIST_FILE = Tests/PolylineTests/Info.plist;
752 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
753 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
754 | PRODUCT_BUNDLE_IDENTIFIER = "com.ramoapps.$(PRODUCT_NAME:rfc1034identifier)";
755 | PRODUCT_NAME = "$(TARGET_NAME)";
756 | };
757 | name = Debug;
758 | };
759 | 207F641619B5DF7E005261FA /* Release */ = {
760 | isa = XCBuildConfiguration;
761 | buildSettings = {
762 | INFOPLIST_FILE = Tests/PolylineTests/Info.plist;
763 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
764 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
765 | PRODUCT_BUNDLE_IDENTIFIER = "com.ramoapps.$(PRODUCT_NAME:rfc1034identifier)";
766 | PRODUCT_NAME = "$(TARGET_NAME)";
767 | };
768 | name = Release;
769 | };
770 | 91F7833E1CE4EB7F004E87E3 /* Debug */ = {
771 | isa = XCBuildConfiguration;
772 | buildSettings = {
773 | CLANG_ANALYZER_NONNULL = YES;
774 | CODE_SIGN_IDENTITY = "";
775 | COMBINE_HIDPI_IMAGES = YES;
776 | DEAD_CODE_STRIPPING = YES;
777 | DEBUG_INFORMATION_FORMAT = dwarf;
778 | DEFINES_MODULE = YES;
779 | DYLIB_COMPATIBILITY_VERSION = 1;
780 | DYLIB_CURRENT_VERSION = 7;
781 | DYLIB_INSTALL_NAME_BASE = "@rpath";
782 | FRAMEWORK_VERSION = A;
783 | GCC_NO_COMMON_BLOCKS = YES;
784 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
785 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
786 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
787 | MACOSX_DEPLOYMENT_TARGET = 10.14;
788 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.Polyline;
789 | PRODUCT_NAME = Polyline;
790 | SDKROOT = macosx;
791 | SKIP_INSTALL = YES;
792 | };
793 | name = Debug;
794 | };
795 | 91F7833F1CE4EB7F004E87E3 /* Release */ = {
796 | isa = XCBuildConfiguration;
797 | buildSettings = {
798 | CLANG_ANALYZER_NONNULL = YES;
799 | CODE_SIGN_IDENTITY = "";
800 | COMBINE_HIDPI_IMAGES = YES;
801 | COPY_PHASE_STRIP = NO;
802 | DEAD_CODE_STRIPPING = YES;
803 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
804 | DEFINES_MODULE = YES;
805 | DYLIB_COMPATIBILITY_VERSION = 1;
806 | DYLIB_CURRENT_VERSION = 7;
807 | DYLIB_INSTALL_NAME_BASE = "@rpath";
808 | FRAMEWORK_VERSION = A;
809 | GCC_NO_COMMON_BLOCKS = YES;
810 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
811 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
812 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
813 | MACOSX_DEPLOYMENT_TARGET = 10.14;
814 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.Polyline;
815 | PRODUCT_NAME = Polyline;
816 | SDKROOT = macosx;
817 | SKIP_INSTALL = YES;
818 | };
819 | name = Release;
820 | };
821 | 91F783411CE4EB7F004E87E3 /* Debug */ = {
822 | isa = XCBuildConfiguration;
823 | buildSettings = {
824 | CLANG_ANALYZER_NONNULL = YES;
825 | CODE_SIGN_IDENTITY = "-";
826 | COMBINE_HIDPI_IMAGES = YES;
827 | DEAD_CODE_STRIPPING = YES;
828 | DEBUG_INFORMATION_FORMAT = dwarf;
829 | GCC_NO_COMMON_BLOCKS = YES;
830 | INFOPLIST_FILE = Tests/PolylineTests/Info.plist;
831 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
832 | MACOSX_DEPLOYMENT_TARGET = 10.14;
833 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests;
834 | PRODUCT_NAME = PolylineTests;
835 | SDKROOT = macosx;
836 | };
837 | name = Debug;
838 | };
839 | 91F783421CE4EB7F004E87E3 /* Release */ = {
840 | isa = XCBuildConfiguration;
841 | buildSettings = {
842 | CLANG_ANALYZER_NONNULL = YES;
843 | CODE_SIGN_IDENTITY = "-";
844 | COMBINE_HIDPI_IMAGES = YES;
845 | COPY_PHASE_STRIP = NO;
846 | DEAD_CODE_STRIPPING = YES;
847 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
848 | GCC_NO_COMMON_BLOCKS = YES;
849 | INFOPLIST_FILE = Tests/PolylineTests/Info.plist;
850 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
851 | MACOSX_DEPLOYMENT_TARGET = 10.14;
852 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests;
853 | PRODUCT_NAME = PolylineTests;
854 | SDKROOT = macosx;
855 | };
856 | name = Release;
857 | };
858 | DA1A10821D003E88009F82FA /* Debug */ = {
859 | isa = XCBuildConfiguration;
860 | buildSettings = {
861 | CLANG_ANALYZER_NONNULL = YES;
862 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
863 | DEBUG_INFORMATION_FORMAT = dwarf;
864 | DEFINES_MODULE = YES;
865 | DYLIB_COMPATIBILITY_VERSION = 1;
866 | DYLIB_CURRENT_VERSION = 7;
867 | DYLIB_INSTALL_NAME_BASE = "@rpath";
868 | GCC_NO_COMMON_BLOCKS = YES;
869 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
870 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
871 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
872 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.Polyline;
873 | PRODUCT_NAME = Polyline;
874 | SDKROOT = appletvos;
875 | SKIP_INSTALL = YES;
876 | TARGETED_DEVICE_FAMILY = 3;
877 | TVOS_DEPLOYMENT_TARGET = 12.0;
878 | };
879 | name = Debug;
880 | };
881 | DA1A10831D003E88009F82FA /* Release */ = {
882 | isa = XCBuildConfiguration;
883 | buildSettings = {
884 | CLANG_ANALYZER_NONNULL = YES;
885 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
886 | COPY_PHASE_STRIP = NO;
887 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
888 | DEFINES_MODULE = YES;
889 | DYLIB_COMPATIBILITY_VERSION = 1;
890 | DYLIB_CURRENT_VERSION = 7;
891 | DYLIB_INSTALL_NAME_BASE = "@rpath";
892 | GCC_NO_COMMON_BLOCKS = YES;
893 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
894 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
895 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
896 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.Polyline;
897 | PRODUCT_NAME = Polyline;
898 | SDKROOT = appletvos;
899 | SKIP_INSTALL = YES;
900 | TARGETED_DEVICE_FAMILY = 3;
901 | TVOS_DEPLOYMENT_TARGET = 12.0;
902 | };
903 | name = Release;
904 | };
905 | DA1A10841D003E88009F82FA /* Debug */ = {
906 | isa = XCBuildConfiguration;
907 | buildSettings = {
908 | CLANG_ANALYZER_NONNULL = YES;
909 | DEBUG_INFORMATION_FORMAT = dwarf;
910 | GCC_NO_COMMON_BLOCKS = YES;
911 | INFOPLIST_FILE = Tests/PolylineTests/Info.plist;
912 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
913 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests;
914 | PRODUCT_NAME = PolylineTests;
915 | SDKROOT = appletvos;
916 | TVOS_DEPLOYMENT_TARGET = 12.0;
917 | };
918 | name = Debug;
919 | };
920 | DA1A10851D003E88009F82FA /* Release */ = {
921 | isa = XCBuildConfiguration;
922 | buildSettings = {
923 | CLANG_ANALYZER_NONNULL = YES;
924 | COPY_PHASE_STRIP = NO;
925 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
926 | GCC_NO_COMMON_BLOCKS = YES;
927 | INFOPLIST_FILE = Tests/PolylineTests/Info.plist;
928 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
929 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.PolylineTests;
930 | PRODUCT_NAME = PolylineTests;
931 | SDKROOT = appletvos;
932 | TVOS_DEPLOYMENT_TARGET = 12.0;
933 | };
934 | name = Release;
935 | };
936 | DA1A10971D00400D009F82FA /* Debug */ = {
937 | isa = XCBuildConfiguration;
938 | buildSettings = {
939 | APPLICATION_EXTENSION_API_ONLY = YES;
940 | CLANG_ANALYZER_NONNULL = YES;
941 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
942 | DEBUG_INFORMATION_FORMAT = dwarf;
943 | DEFINES_MODULE = YES;
944 | DYLIB_COMPATIBILITY_VERSION = 1;
945 | DYLIB_CURRENT_VERSION = 7;
946 | DYLIB_INSTALL_NAME_BASE = "@rpath";
947 | GCC_NO_COMMON_BLOCKS = YES;
948 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
949 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
950 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
951 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.Polyline;
952 | PRODUCT_NAME = Polyline;
953 | SDKROOT = watchos;
954 | SKIP_INSTALL = YES;
955 | TARGETED_DEVICE_FAMILY = 4;
956 | WATCHOS_DEPLOYMENT_TARGET = 5.0;
957 | };
958 | name = Debug;
959 | };
960 | DA1A10981D00400D009F82FA /* Release */ = {
961 | isa = XCBuildConfiguration;
962 | buildSettings = {
963 | APPLICATION_EXTENSION_API_ONLY = YES;
964 | CLANG_ANALYZER_NONNULL = YES;
965 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
966 | COPY_PHASE_STRIP = NO;
967 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
968 | DEFINES_MODULE = YES;
969 | DYLIB_COMPATIBILITY_VERSION = 1;
970 | DYLIB_CURRENT_VERSION = 7;
971 | DYLIB_INSTALL_NAME_BASE = "@rpath";
972 | GCC_NO_COMMON_BLOCKS = YES;
973 | INFOPLIST_FILE = Sources/Polyline/Info.plist;
974 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
975 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
976 | PRODUCT_BUNDLE_IDENTIFIER = com.ramoapps.Polyline;
977 | PRODUCT_NAME = Polyline;
978 | SDKROOT = watchos;
979 | SKIP_INSTALL = YES;
980 | TARGETED_DEVICE_FAMILY = 4;
981 | WATCHOS_DEPLOYMENT_TARGET = 5.0;
982 | };
983 | name = Release;
984 | };
985 | /* End XCBuildConfiguration section */
986 |
987 | /* Begin XCConfigurationList section */
988 | 207F63F819B5DF7E005261FA /* Build configuration list for PBXProject "Polyline" */ = {
989 | isa = XCConfigurationList;
990 | buildConfigurations = (
991 | 207F640F19B5DF7E005261FA /* Debug */,
992 | 207F641019B5DF7E005261FA /* Release */,
993 | );
994 | defaultConfigurationIsVisible = 0;
995 | defaultConfigurationName = Release;
996 | };
997 | 207F641119B5DF7E005261FA /* Build configuration list for PBXNativeTarget "Polyline" */ = {
998 | isa = XCConfigurationList;
999 | buildConfigurations = (
1000 | 207F641219B5DF7E005261FA /* Debug */,
1001 | 207F641319B5DF7E005261FA /* Release */,
1002 | );
1003 | defaultConfigurationIsVisible = 0;
1004 | defaultConfigurationName = Release;
1005 | };
1006 | 207F641419B5DF7E005261FA /* Build configuration list for PBXNativeTarget "PolylineTests" */ = {
1007 | isa = XCConfigurationList;
1008 | buildConfigurations = (
1009 | 207F641519B5DF7E005261FA /* Debug */,
1010 | 207F641619B5DF7E005261FA /* Release */,
1011 | );
1012 | defaultConfigurationIsVisible = 0;
1013 | defaultConfigurationName = Release;
1014 | };
1015 | 91F7833D1CE4EB7F004E87E3 /* Build configuration list for PBXNativeTarget "PolylineMac" */ = {
1016 | isa = XCConfigurationList;
1017 | buildConfigurations = (
1018 | 91F7833E1CE4EB7F004E87E3 /* Debug */,
1019 | 91F7833F1CE4EB7F004E87E3 /* Release */,
1020 | );
1021 | defaultConfigurationIsVisible = 0;
1022 | defaultConfigurationName = Release;
1023 | };
1024 | 91F783401CE4EB7F004E87E3 /* Build configuration list for PBXNativeTarget "PolylineMacTests" */ = {
1025 | isa = XCConfigurationList;
1026 | buildConfigurations = (
1027 | 91F783411CE4EB7F004E87E3 /* Debug */,
1028 | 91F783421CE4EB7F004E87E3 /* Release */,
1029 | );
1030 | defaultConfigurationIsVisible = 0;
1031 | defaultConfigurationName = Release;
1032 | };
1033 | DA1A10861D003E88009F82FA /* Build configuration list for PBXNativeTarget "PolylineTV" */ = {
1034 | isa = XCConfigurationList;
1035 | buildConfigurations = (
1036 | DA1A10821D003E88009F82FA /* Debug */,
1037 | DA1A10831D003E88009F82FA /* Release */,
1038 | );
1039 | defaultConfigurationIsVisible = 0;
1040 | defaultConfigurationName = Release;
1041 | };
1042 | DA1A10871D003E88009F82FA /* Build configuration list for PBXNativeTarget "PolylineTVTests" */ = {
1043 | isa = XCConfigurationList;
1044 | buildConfigurations = (
1045 | DA1A10841D003E88009F82FA /* Debug */,
1046 | DA1A10851D003E88009F82FA /* Release */,
1047 | );
1048 | defaultConfigurationIsVisible = 0;
1049 | defaultConfigurationName = Release;
1050 | };
1051 | DA1A10961D00400D009F82FA /* Build configuration list for PBXNativeTarget "PolylineWatch" */ = {
1052 | isa = XCConfigurationList;
1053 | buildConfigurations = (
1054 | DA1A10971D00400D009F82FA /* Debug */,
1055 | DA1A10981D00400D009F82FA /* Release */,
1056 | );
1057 | defaultConfigurationIsVisible = 0;
1058 | defaultConfigurationName = Release;
1059 | };
1060 | /* End XCConfigurationList section */
1061 | };
1062 | rootObject = 207F63F519B5DF7E005261FA /* Project object */;
1063 | }
1064 |
--------------------------------------------------------------------------------