Skip to content

Commit

Permalink
Merge pull request #3 from mapbox/feature/spm-binary
Browse files Browse the repository at this point in the history
Swift Package Manager support — Binary distribution
  • Loading branch information
OdNairy authored Jun 28, 2021
2 parents c689002 + 22a7014 commit 564136d
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

.swiftpm
8 changes: 4 additions & 4 deletions Cartfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
binary "https://api.mapbox.com/downloads/v2/carthage/search-sdk/MapboxSearch.json" == 1.0.0-beta.5
binary "https://api.mapbox.com/downloads/v2/carthage/search-sdk/MapboxSearchUI.json" == 1.0.0-beta.5
binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon.json" ~> 11.0.0
github "mapbox/mapbox-events-ios" ~> 0.10.0
binary "https://api.mapbox.com/downloads/v2/carthage/search-sdk/MapboxSearch.json" == 1.0.0-beta.6
binary "https://api.mapbox.com/downloads/v2/carthage/search-sdk/MapboxSearchUI.json" == 1.0.0-beta.6
binary "https://api.mapbox.com/downloads/v2/carthage/mapbox-common/MapboxCommon.json" ~> 13.0.0
github "mapbox/mapbox-events-ios" ~> 1.0.0
25 changes: 25 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"object": {
"pins": [
{
"package": "MapboxCommon",
"repositoryURL": "git@github.com:mapbox/mapbox-common-ios.git",
"state": {
"branch": null,
"revision": "16e7bb71288b7835e420ba8213c1c45276338839",
"version": "13.0.0"
}
},
{
"package": "MapboxMobileEvents",
"repositoryURL": "https://github.com/mapbox/mapbox-events-ios",
"state": {
"branch": null,
"revision": "8e0c725271dee0a0c957b9b9738aef81b601f12b",
"version": "1.0.2"
}
}
]
},
"version": 1
}
181 changes: 181 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.


import PackageDescription
import Foundation

let registry = SDKRegistry()

let (searchVersion, searchVersionHash) = ("1.0.0-beta.6", "27b630300a2647fc33da3208b63321b4c1cef7478ab531aabaea605998ce536c")
let (searchUIVersion, searchUIVersionHash) = ("1.0.0-beta.6", "a273c17b9c778d5f5617933bf93575719c2c914c99209a73bf3c110826f54fdc")


let package = Package(
name: "MapboxSearch",
platforms: [
.iOS(.v11)
],
products: [
.library(
name: "MapboxSearch",
targets: [
"MapboxSearchDependencies",
"MapboxSearch"
]
),
.library(
name: "MapboxSearchUI",
targets: [
"MapboxSearchUI"
]
),
],
dependencies: [
.package(name: "MapboxMobileEvents",
url: "https://github.com/mapbox/mapbox-events-ios",
from: "1.0.0"),
.package(name: "MapboxCommon",
url: "git@github.com:mapbox/mapbox-common-ios.git",
from: "13.0.0"),
],
targets: [
.target(name: "MapboxSearchDependencies",
dependencies: [
"MapboxMobileEvents",
"MapboxCommon"
]),
registry.mapboxSearchTarget(version: searchVersion,
checksum: searchVersionHash),
registry.mapboxSearchUITarget(version: searchUIVersion,
checksum: searchUIVersionHash)
],
cxxLanguageStandard: .cxx14
)


struct SDKRegistry {
let host = "api.mapbox.com"

func binaryTarget(name: String, version: String, path: String, filename: String, checksum: String) -> Target {
var url = "https://\(host)/downloads/v2/\(path)/releases/ios/packages/\(version)/\(filename)"

if let token = netrcToken {
url += "?access_token=\(token)"
} else {
debugPrint("Mapbox token wasn't founded in ~/.netrc. Fix this issue to integrate Mapbox SDK. Otherwise, you will see 'invalid status code 401' or 'no XCFramework found. To clean issue in Xcode, remove ~/Library/Developer/Xcode/DerivedData folder")
}

return .binaryTarget(name: name, url: url, checksum: checksum)
}

var netrcToken: String? {
var mapboxToken: String?
do {
let netrc = try Netrc.load().get()
mapboxToken = netrc.machines.first(where: { $0.name == host })?.password
} catch {
// Do nothing on client machines
}

return mapboxToken
}
}

extension SDKRegistry {
func mapboxSearchTarget(version: String, checksum: String) -> Target {
return binaryTarget(name: "MapboxSearch",
version: version,
path: "search-sdk",
filename: "MapboxSearch.zip",
checksum: checksum)
}
func mapboxSearchUITarget(version: String, checksum: String) -> Target {
return binaryTarget(name: "MapboxSearchUI",
version: version,
path: "search-sdk",
filename: "MapboxSearchUI.zip",
checksum: checksum)
}
}

// Reference: https://github.com/apple/swift-tools-support-core/pull/88
// Sub-reference: https://github.com/Carthage/Carthage/pull/2774
struct NetrcMachine {
let name: String
let login: String
let password: String
}

struct Netrc {

enum NetrcError: Error {
case fileNotFound(URL)
case unreadableFile(URL)
case machineNotFound
case missingToken(String)
case missingValueForToken(String)
}

public let machines: [NetrcMachine]

init(machines: [NetrcMachine]) {
self.machines = machines
}

static func load(from fileURL: URL = URL(fileURLWithPath: "\(NSHomeDirectory())/.netrc")) -> Result<Netrc, Error> {
guard FileManager.default.fileExists(atPath: fileURL.path) else { return .failure(NetrcError.fileNotFound(fileURL)) }
guard FileManager.default.isReadableFile(atPath: fileURL.path) else { return .failure(NetrcError.unreadableFile(fileURL)) }

return Result(catching: { try String(contentsOf: fileURL, encoding: .utf8) })
.flatMap { Netrc.from($0) }
}

static func from(_ content: String) -> Result<Netrc, Error> {
let trimmedCommentsContent = trimComments(from: content)
let tokens = trimmedCommentsContent
.trimmingCharacters(in: .whitespacesAndNewlines)
.components(separatedBy: .whitespacesAndNewlines)
.filter({ $0 != "" })

var machines: [NetrcMachine] = []

let machineTokens = tokens.split { $0 == "machine" }
guard tokens.contains("machine"), machineTokens.count > 0 else { return .failure(NetrcError.machineNotFound) }

for machine in machineTokens {
let values = Array(machine)
guard let name = values.first else { continue }
guard let login = values["login"] else { return .failure(NetrcError.missingValueForToken("login")) }
guard let password = values["password"] else { return .failure(NetrcError.missingValueForToken("password")) }
machines.append(NetrcMachine(name: name, login: login, password: password))
}

guard machines.count > 0 else { return .failure(NetrcError.machineNotFound) }
return .success(Netrc(machines: machines))
}

private static func trimComments(from text: String) -> String {
let regex = try! NSRegularExpression(pattern: "\\#[\\s\\S]*?.*$", options: .anchorsMatchLines)
let nsString = text as NSString
let range = NSRange(location: 0, length: nsString.length)
let matches = regex.matches(in: text, range: range)
var trimmedCommentsText = text
matches.forEach {
trimmedCommentsText = trimmedCommentsText
.replacingOccurrences(of: nsString.substring(with: $0.range), with: "")
}
return trimmedCommentsText
}
}

fileprivate extension Array where Element == String {
subscript(_ token: String) -> String? {
guard let tokenIndex = firstIndex(of: token),
count > tokenIndex,
!["machine", "login", "password"].contains(self[tokenIndex + 1]) else {
return nil
}
return self[tokenIndex + 1]
}
}
1 change: 1 addition & 0 deletions Sources/MapboxSearchDependencies/Dummy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

0 comments on commit 564136d

Please sign in to comment.