diff --git a/.gitignore b/.gitignore
index d36329c..fe42201 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,11 +2,14 @@ libtailscale.so
libtailscale.a
libtailscale.h
libtailscale.tar*
+libtailscale_ios.a
+libtailscale_ios.h
/tstestcontrol/libtstestcontrol.a
/tstestcontrol/libtstestcontrol.h
/swift/build
+**/xcuserdata/**
/ruby/tmp/
/ruby/pkg/
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4157cb8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,34 @@
+# Copyright (c) Tailscale Inc & AUTHORS
+# SPDX-License-Identifier: BSD-3-Clause
+
+
+libtailscale.a:
+ go build -buildmode=c-archive
+
+libtailscale_ios.a:
+ GOOS=ios GOARCH=arm64 CGO_ENABLED=1 CC=$(PWD)/swift/script/clangwrap.sh /usr/local/go/bin/go build -v -ldflags -w -tags ios -o libtailscale_ios.a -buildmode=c-archive
+
+.PHONY: c-archive-ios
+c-archive-ios: libtailscale_ios.a ## Builds libtailscale_ios.a for iOS (iOS SDK required)
+
+.PHONY: c-archive
+c-archive: libtailscale.a ## Builds libtailscale.a for the target platform
+
+.PHONY: shared
+shared: ## Builds libtailscale.so for the target platform
+ go build -v -buildmode=c-shared
+
+.PHONY: clean
+clean: ## Clean up build artifacts
+ rm -f libtailscale.a
+ rm -f libtailscale_ios.a
+ rm -f libtailscale.h
+ rm -f libtailscale_ios.h
+
+.PHONY: help
+help: ## Show this help
+ @echo "\nSpecify a command. The choices are:\n"
+ @grep -hE '^[0-9a-zA-Z_-]+:.*?## .*$$' ${MAKEFILE_LIST} | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[0;36m%-12s\033[m %s\n", $$1, $$2}'
+ @echo ""
+
+.DEFAULT_GOAL := help
diff --git a/README.md b/README.md
index dca88f2..54375b6 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,12 @@ With the latest version of Go, run:
go build -buildmode=c-archive
```
+or
+
+```
+make archive
+```
+
This will produce a `libtailscale.a` file. Link it into your binary,
and use the `tailscale.h` header to reference it.
@@ -22,6 +28,12 @@ It is also possible to build a shared library using
go build -buildmode=c-shared
```
+or
+
+```
+make shared
+```
+
## Bugs
Please file any issues about this code or the hosted service on
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/AccentColor.colorset/Contents.json b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/AppIcon.appiconset/Contents.json b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..3f00db4
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "16x16"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "16x16"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "32x32"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "32x32"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "128x128"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "128x128"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "256x256"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "256x256"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "1x",
+ "size" : "512x512"
+ },
+ {
+ "idiom" : "mac",
+ "scale" : "2x",
+ "size" : "512x512"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/Contents.json b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloFromTailscale.entitlements b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloFromTailscale.entitlements
new file mode 100644
index 0000000..40b639e
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloFromTailscale.entitlements
@@ -0,0 +1,14 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+ com.apple.security.network.client
+
+ com.apple.security.network.server
+
+
+
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloFromTailscaleApp.swift b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloFromTailscaleApp.swift
new file mode 100644
index 0000000..8ec6999
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloFromTailscaleApp.swift
@@ -0,0 +1,15 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+import SwiftUI
+
+@main
+struct HelloFromTailscaleApp: App {
+ let manager = HelloManager()
+
+ var body: some Scene {
+ WindowGroup {
+ HelloView(dialer: manager)
+ }
+ }
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloManager.swift b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloManager.swift
new file mode 100644
index 0000000..1c51320
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloManager.swift
@@ -0,0 +1,71 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+import Foundation
+import TailscaleKit
+
+enum HelloError: Error {
+ case noNode
+}
+
+typealias MessageSender = @Sendable (String) async -> Void
+
+struct Logger: TailscaleKit.LogSink {
+ var logFileHandle: Int32? = STDOUT_FILENO
+
+ func log(_ message: String) {
+ print(message)
+ }
+}
+
+protocol Dialer: Actor {
+ func phoneHome(_ setMessage: @escaping MessageSender) async
+}
+
+actor HelloManager: Dialer {
+ var node: TailscaleNode?
+
+ let logger = Logger()
+ let config: Configuration
+
+ init() {
+ let temp = getDocumentDirectoryPath().absoluteString + "tailscale"
+ self.config = Configuration(hostName: Settings.hostName,
+ path: temp,
+ authKey: Settings.authKey,
+ controlURL: kDefaultControlURL,
+ ephemeral: true)
+ }
+
+ func setupNode() throws -> TailscaleNode {
+ guard self.node == nil else { return self.node! }
+ self.node = try TailscaleNode(config: config, logger: logger)
+ return self.node!
+ }
+
+ func phoneHome(_ setMessage: @escaping MessageSender) async {
+ do {
+ let node = try setupNode()
+ await setMessage("Connecting to Tailnet...")
+
+ try await node.up()
+
+ await setMessage("Phoning " + Settings.tailnetServer + "...")
+
+ // Create a URLSession that can access nodes on the tailnet.
+ // .tailscaleSession(node) is the magic sauce. This sends your URLRequest via
+ // userspace Tailscale's SOCKS5 proxy.
+ let sessionConfig = try await URLSessionConfiguration.tailscaleSession(node)
+ let session = URLSession(configuration: sessionConfig)
+
+ // Request a resource from the tailnet...
+ let url = URL(string: Settings.tailnetServer)!
+ let req = URLRequest(url: url)
+
+ let (data, _) = try await session.data(for: req)
+ await setMessage("\(Settings.tailnetServer) says:\n \(String(data: data, encoding: .utf8) ?? "(crickets!)")")
+ } catch {
+ await setMessage("Whoops!: \(error)")
+ }
+ }
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloView.swift b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloView.swift
new file mode 100644
index 0000000..de928a9
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloView.swift
@@ -0,0 +1,41 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+import SwiftUI
+
+
+struct HelloView: View {
+ @ObservedObject var model : HelloViewModel
+ let dialer: Dialer
+
+ init(dialer: Dialer) {
+ self.dialer = dialer
+ self.model = HelloViewModel()
+ }
+
+
+ var body: some View {
+ VStack {
+ Text("TailscaleKit Sample App. See README.md for setup instructions.")
+ .font(.title)
+ .padding(20)
+ Text(model.message)
+ .font(.title2)
+ Button("Phone Home!") {
+ model.runRequest(dialer)
+ }
+ }
+ .padding()
+ }
+}
+
+actor PreviewDialer: Dialer {
+ func phoneHome(_ setMessage: @escaping @Sendable (String) async -> Void) async {
+ await setMessage("Hello from Preview!")
+ }
+}
+
+#Preview {
+ let d = PreviewDialer()
+ HelloView(dialer: d)
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloViewModel.swift b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloViewModel.swift
new file mode 100644
index 0000000..95cb318
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/HelloViewModel.swift
@@ -0,0 +1,21 @@
+
+
+import SwiftUI
+import Combine
+import TailscaleKit
+
+class HelloViewModel: ObservableObject, @unchecked Sendable {
+ @Published var message: String = "Ready to phone home!"
+
+ func setMessage(_ message: String) async {
+ await MainActor.run {
+ self.message = message
+ }
+ }
+
+ func runRequest(_ dialer: Dialer) {
+ Task {
+ await dialer.phoneHome(setMessage)
+ }
+ }
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/Info.plist b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Info.plist
new file mode 100644
index 0000000..365ab61
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Info.plist
@@ -0,0 +1,19 @@
+
+
+
+
+ NSAppTransportSecurity
+
+ NSExceptionDomains
+
+ ts.net
+
+ NSExceptionAllowsInsecureHTTPLoads
+
+ NSIncludesSubdomains
+
+
+
+
+
+
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/Preview Content/Preview Assets.xcassets/Contents.json b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/swift/Examples/TailscaleKitHello/HelloFromTailscale/TailnetSettings.swift b/swift/Examples/TailscaleKitHello/HelloFromTailscale/TailnetSettings.swift
new file mode 100644
index 0000000..ea24492
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/HelloFromTailscale/TailnetSettings.swift
@@ -0,0 +1,20 @@
+// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+import Foundation
+
+struct Settings {
+ // Replace with an actual auth key generated from the Tailscale admin console
+ static let authKey = "tskey-auth-somekey"
+ // Note: The sample has a transport exception for http on ts.net so http:// is ok...
+ static let tailnetServer = "http://myserver.my-tailnet.ts.net"
+ // Identifies this application in the Tailscale admin console.
+ static let hostName = "Hello-From-Tailsacle-Sample-App"
+}
+
+
+func getDocumentDirectoryPath() -> URL {
+ let arrayPaths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
+ let docDirectoryPath = arrayPaths[0]
+ return docDirectoryPath
+}
diff --git a/swift/Examples/TailscaleKitHello/README.md b/swift/Examples/TailscaleKitHello/README.md
new file mode 100644
index 0000000..1500909
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/README.md
@@ -0,0 +1,19 @@
+# TailscaleKitHello
+
+## Instructions
+
+First build TailscaleKit:
+
+From /swift:
+```
+$ make macos
+```
+
+In TailnetSettings, configure an auth key and a server/service to query.
+
+```
+let authKey = "your-auth-key-here"
+let tailnetServer = "http://your-server-here.your-tailnet.ts.net"
+```
+
+Run the project. Phone Home. The output should be the response from the server.
diff --git a/swift/Examples/TailscaleKitHello/TailscaleKitHello.xcodeproj/project.pbxproj b/swift/Examples/TailscaleKitHello/TailscaleKitHello.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..ee16377
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/TailscaleKitHello.xcodeproj/project.pbxproj
@@ -0,0 +1,373 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 77;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ C25260032D7A71E800BD3CCA /* TailscaleKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2525FC52D7A69DE00BD3CCA /* TailscaleKit.framework */; };
+ C25260052D7A71FE00BD3CCA /* TailscaleKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C2525FC52D7A69DE00BD3CCA /* TailscaleKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ C25260042D7A71F300BD3CCA /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ C25260052D7A71FE00BD3CCA /* TailscaleKit.framework in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ C2525FC52D7A69DE00BD3CCA /* TailscaleKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TailscaleKit.framework; path = ../../build/Build/Products/Release/TailscaleKit.framework; sourceTree = ""; };
+ C2525FF12D7A70B700BD3CCA /* HelloFromTailscale.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloFromTailscale.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ C25260082D7A7DC400BD3CCA /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
+ C25260072D7A7BAE00BD3CCA /* Exceptions for "HelloFromTailscale" folder in "HelloFromTailscale" target */ = {
+ isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ Info.plist,
+ );
+ target = C2525FF02D7A70B700BD3CCA /* HelloFromTailscale */;
+ };
+/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
+
+/* Begin PBXFileSystemSynchronizedRootGroup section */
+ C2525FF22D7A70B700BD3CCA /* HelloFromTailscale */ = {
+ isa = PBXFileSystemSynchronizedRootGroup;
+ exceptions = (
+ C25260072D7A7BAE00BD3CCA /* Exceptions for "HelloFromTailscale" folder in "HelloFromTailscale" target */,
+ );
+ path = HelloFromTailscale;
+ sourceTree = "";
+ };
+/* End PBXFileSystemSynchronizedRootGroup section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ C2525FEE2D7A70B700BD3CCA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C25260032D7A71E800BD3CCA /* TailscaleKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ C2525FB12D7A69A500BD3CCA = {
+ isa = PBXGroup;
+ children = (
+ C25260082D7A7DC400BD3CCA /* README.md */,
+ C2525FF22D7A70B700BD3CCA /* HelloFromTailscale */,
+ C2525FC42D7A69DE00BD3CCA /* Frameworks */,
+ C2525FBB2D7A69A500BD3CCA /* Products */,
+ );
+ sourceTree = "";
+ };
+ C2525FBB2D7A69A500BD3CCA /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ C2525FF12D7A70B700BD3CCA /* HelloFromTailscale.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ C2525FC42D7A69DE00BD3CCA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ C2525FC52D7A69DE00BD3CCA /* TailscaleKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ C2525FF02D7A70B700BD3CCA /* HelloFromTailscale */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C2525FFD2D7A70B900BD3CCA /* Build configuration list for PBXNativeTarget "HelloFromTailscale" */;
+ buildPhases = (
+ C2525FED2D7A70B700BD3CCA /* Sources */,
+ C2525FEE2D7A70B700BD3CCA /* Frameworks */,
+ C2525FEF2D7A70B700BD3CCA /* Resources */,
+ C25260042D7A71F300BD3CCA /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ C2525FF22D7A70B700BD3CCA /* HelloFromTailscale */,
+ );
+ name = HelloFromTailscale;
+ packageProductDependencies = (
+ );
+ productName = HelloFromTailscale;
+ productReference = C2525FF12D7A70B700BD3CCA /* HelloFromTailscale.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ C2525FB22D7A69A500BD3CCA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1620;
+ LastUpgradeCheck = 1620;
+ TargetAttributes = {
+ C2525FF02D7A70B700BD3CCA = {
+ CreatedOnToolsVersion = 16.2;
+ };
+ };
+ };
+ buildConfigurationList = C2525FB52D7A69A500BD3CCA /* Build configuration list for PBXProject "TailscaleKitHello" */;
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = C2525FB12D7A69A500BD3CCA;
+ minimizedProjectReferenceProxies = 1;
+ preferredProjectObjectVersion = 77;
+ productRefGroup = C2525FBB2D7A69A500BD3CCA /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ C2525FF02D7A70B700BD3CCA /* HelloFromTailscale */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ C2525FEF2D7A70B700BD3CCA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ C2525FED2D7A70B700BD3CCA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ C2525FBF2D7A69A500BD3CCA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MACOSX_DEPLOYMENT_TARGET = 15.2;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ C2525FC02D7A69A500BD3CCA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MACOSX_DEPLOYMENT_TARGET = 15.2;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = macosx;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ };
+ name = Release;
+ };
+ C2525FFE2D7A70B900BD3CCA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = HelloFromTailscale/HelloFromTailscale.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"HelloFromTailscale/Preview Content\"";
+ DEVELOPMENT_TEAM = W5364U7YZB;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_PREVIEWS = YES;
+ FRAMEWORK_SEARCH_PATHS = "../../build/Build/**";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = HelloFromTailscale/Info.plist;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = io.tailscale.HelloFromTailscale;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 6.0;
+ };
+ name = Debug;
+ };
+ C2525FFF2D7A70B900BD3CCA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = HelloFromTailscale/HelloFromTailscale.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"HelloFromTailscale/Preview Content\"";
+ DEVELOPMENT_TEAM = W5364U7YZB;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_PREVIEWS = YES;
+ FRAMEWORK_SEARCH_PATHS = "../../build/Build/**";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = HelloFromTailscale/Info.plist;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = io.tailscale.HelloFromTailscale;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 6.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ C2525FB52D7A69A500BD3CCA /* Build configuration list for PBXProject "TailscaleKitHello" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C2525FBF2D7A69A500BD3CCA /* Debug */,
+ C2525FC02D7A69A500BD3CCA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C2525FFD2D7A70B900BD3CCA /* Build configuration list for PBXNativeTarget "HelloFromTailscale" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C2525FFE2D7A70B900BD3CCA /* Debug */,
+ C2525FFF2D7A70B900BD3CCA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = C2525FB22D7A69A500BD3CCA /* Project object */;
+}
diff --git a/swift/Examples/TailscaleKitHello/TailscaleKitHello.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/Examples/TailscaleKitHello/TailscaleKitHello.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/swift/Examples/TailscaleKitHello/TailscaleKitHello.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/swift/Makefile b/swift/Makefile
index 375ceb2..5e89882 100644
--- a/swift/Makefile
+++ b/swift/Makefile
@@ -7,14 +7,45 @@ ifeq (, $(shell which $(XCPRETTIFIER)))
XCPRETTIFIER := cat
endif
-OUTPUT_DIR=build
+# The xcodebuild schemes will run the Makefile in the root directory to build
+# the libtailscale.a and libtailscale_ios.a dependencies.
-build:
- mkdir -p $(OUTPUT_DIR)
- xcodebuild build -scheme TailscaleKit -derivedDataPath $(OUTPUT_DIR) -configuration Release -destination 'generic/platform=macOS,arch=arm64' -destination 'generic/platform=iOS' | $(XCPRETTIFIER)
+.PHONY: macos
+macos: ## Builds TailscaleKit for macos to swift/build/Build/Products/Release
+ cd .. && make c-archive
+ mkdir -p build
+ xcodebuild build -scheme "TailscaleKit (macOS)" \
+ -derivedDataPath build \
+ -configuration Release \
+ -destination 'platform=macOS,arch=arm64' | $(XCPRETTIFIER)
-test:
- xcodebuild test -scheme TailscaleKitXCTests -derivedDataPath $(OUTPUT_DIR) -configuration Debug | $(XCPRETTIFIER)
+.PHONY: ios
+ios: ## Builds TailscaleKit for iOS to swift/build/Build/Products/Release
+ cd .. && make c-archive-ios
+ mkdir -p build
+ xcodebuild build -scheme "TailscaleKit (iOS)" \
+ -derivedDataPath build \
+ -configuration Release \
+ -destination 'generic/platform=iOS' | $(XCPRETTIFIER)
-clean:
- rm -rf $(OUTPUT_DIR)
\ No newline at end of file
+.PHONY: test
+test: ## Run tests (macOS)
+ cd .. && make c-archive
+ mkdir -p build
+ xcodebuild test -scheme TailscaleKitXCTests \
+ -derivedDataPath build \
+ -configuration Debug \
+ -destination 'platform=macOS,arch=arm64' | $(XCPRETTIFIER)
+
+.PHONY: clean
+clean: ## Clean up build artifacts (including the libtailscale dependencies)
+ cd .. && make clean
+ rm -rf build
+
+.PHONY: help
+help: ## Show this help
+ @echo "\nSpecify a command. The choices are:\n"
+ @grep -hE '^[0-9a-zA-Z_-]+:.*?## .*$$' ${MAKEFILE_LIST} | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[0;36m%-12s\033[m %s\n", $$1, $$2}'
+ @echo ""
+
+.DEFAULT_GOAL := help
diff --git a/swift/README.md b/swift/README.md
index 1ca7199..e686239 100644
--- a/swift/README.md
+++ b/swift/README.md
@@ -14,9 +14,14 @@ Build Requirements:
Building Tailscale.framework:
+First build the libtailscale dependecies:
+
+
+
From /swift
```
-$ make build
+$ make macos
+# make ios
```
Will build TailscaleKit.framework into /swift/build/Build/Products.
@@ -24,7 +29,15 @@ Will build TailscaleKit.framework into /swift/build/Build/Products.
Separate frameworks will be built for macOS and iOS. All dependencies (libtailscale.a)
are built automatically. Swift 6 is supported.
-Alternatively, you may build from xCode using the Tailscale scheme.
+Alternatively, you may build from xCode using the Tailscale scheme but the
+libraries must be built first (since xCode will complain about paths and
+permissions)
+
+From /
+```
+$ make c-archive
+$ make c-archive-ios
+```
Non-apple builds are not supported (yet). We do use URLSession and Combine though
it is possible to purge both.
diff --git a/swift/TailscaleKit.xcodeproj/project.pbxproj b/swift/TailscaleKit.xcodeproj/project.pbxproj
index a132530..cd81c47 100644
--- a/swift/TailscaleKit.xcodeproj/project.pbxproj
+++ b/swift/TailscaleKit.xcodeproj/project.pbxproj
@@ -20,22 +20,10 @@
);
productName = libtailscale;
};
- C2EE3B622CCBE88400CF5BE0 /* libtailscale */ = {
- isa = PBXAggregateTarget;
- buildConfigurationList = C2EE3B632CCBE88400CF5BE0 /* Build configuration list for PBXAggregateTarget "libtailscale" */;
- buildPhases = (
- C2EE3B662CCBE88E00CF5BE0 /* ShellScript */,
- );
- dependencies = (
- );
- name = libtailscale;
- packageProductDependencies = (
- );
- productName = libtailscale;
- };
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
+ C2525F542D7A258D00BD3CCA /* libtailscale_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C2525F532D7A258D00BD3CCA /* libtailscale_ios.a */; };
C2BED05D2CCFC68D004A2544 /* libtstestcontrol.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C2BED05C2CCFC68D004A2544 /* libtstestcontrol.a */; };
C2E1C30B2CC9EF1A00ADC565 /* libtailscale.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C2E1C2FC2CC9B9E300ADC565 /* libtailscale.a */; };
C2E1C3142CCA8B7C00ADC565 /* TailscaleKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2E1C2DA2CC9B5A400ADC565 /* TailscaleKit.framework */; };
@@ -63,32 +51,39 @@
remoteGlobalIDString = C2E1C2D92CC9B5A400ADC565;
remoteInfo = Tailscale;
};
- C2EE3B692CCBED1E00CF5BE0 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = C2E1C2D12CC9B5A400ADC565 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = C2EE3B622CCBE88400CF5BE0;
- remoteInfo = libtailscale;
- };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ C2525F4E2D7A22C100BD3CCA /* TailscaleKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TailscaleKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ C2525F532D7A258D00BD3CCA /* libtailscale_ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtailscale_ios.a; path = ../libtailscale_ios.a; sourceTree = ""; };
C28640622CCA8C9D00CD5EBC /* TailscaleKitTestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TailscaleKitTestHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
C2BED05C2CCFC68D004A2544 /* libtstestcontrol.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtstestcontrol.a; path = ../tstestconrol/libtstestcontrol.a; sourceTree = ""; };
C2E1C2DA2CC9B5A400ADC565 /* TailscaleKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TailscaleKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C2E1C2FC2CC9B9E300ADC565 /* libtailscale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtailscale.a; path = ../libtailscale.a; sourceTree = ""; };
C2E1C3102CCA8B7C00ADC565 /* TailscaleKitXCTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TailscaleKitXCTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
C2E3E87F2D2718D0004992A2 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
- C2E3E8802D2718D6004992A2 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
- C2E1C2EC2CC9B5A400ADC565 /* Exceptions for "TailscaleKit" folder in "TailscaleKit" target */ = {
+ C2525F4F2D7A22C100BD3CCA /* Exceptions for "TailscaleKit" folder in "TailscaleKit iOS" target */ = {
+ isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ TailscaleKit.docc,
+ );
+ publicHeaders = (
+ TailscaleKit.h,
+ );
+ target = C2525F432D7A22C100BD3CCA /* TailscaleKit iOS */;
+ };
+ C2E1C2EC2CC9B5A400ADC565 /* Exceptions for "TailscaleKit" folder in "TailscaleKit macOS" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ TailscaleKit.docc,
+ );
publicHeaders = (
TailscaleKit.h,
);
- target = C2E1C2D92CC9B5A400ADC565 /* TailscaleKit */;
+ target = C2E1C2D92CC9B5A400ADC565 /* TailscaleKit macOS */;
};
C2E3E87E2D2711BF004992A2 /* Exceptions for "TailscaleKitTestHost" folder in "TailscaleKitTestHost" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
@@ -121,7 +116,8 @@
C2E1C2DC2CC9B5A400ADC565 /* TailscaleKit */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
- C2E1C2EC2CC9B5A400ADC565 /* Exceptions for "TailscaleKit" folder in "TailscaleKit" target */,
+ C2E1C2EC2CC9B5A400ADC565 /* Exceptions for "TailscaleKit" folder in "TailscaleKit macOS" target */,
+ C2525F4F2D7A22C100BD3CCA /* Exceptions for "TailscaleKit" folder in "TailscaleKit iOS" target */,
);
path = TailscaleKit;
sourceTree = "";
@@ -137,6 +133,14 @@
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
+ C2525F482D7A22C100BD3CCA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C2525F542D7A258D00BD3CCA /* libtailscale_ios.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
C286405F2CCA8C9D00CD5EBC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -167,7 +171,6 @@
C2E1C2D02CC9B5A400ADC565 = {
isa = PBXGroup;
children = (
- C2E3E8802D2718D6004992A2 /* Makefile */,
C2E3E87F2D2718D0004992A2 /* README.md */,
C2E1C2DC2CC9B5A400ADC565 /* TailscaleKit */,
C2E1C3112CCA8B7C00ADC565 /* TailscaleKitXCTests */,
@@ -183,6 +186,7 @@
C2E1C2DA2CC9B5A400ADC565 /* TailscaleKit.framework */,
C2E1C3102CCA8B7C00ADC565 /* TailscaleKitXCTests.xctest */,
C28640622CCA8C9D00CD5EBC /* TailscaleKitTestHost.app */,
+ C2525F4E2D7A22C100BD3CCA /* TailscaleKit.framework */,
);
name = Products;
sourceTree = "";
@@ -190,6 +194,7 @@
C2E1C2FB2CC9B9E300ADC565 /* Frameworks */ = {
isa = PBXGroup;
children = (
+ C2525F532D7A258D00BD3CCA /* libtailscale_ios.a */,
C2BED05C2CCFC68D004A2544 /* libtstestcontrol.a */,
C2E1C2FC2CC9B9E300ADC565 /* libtailscale.a */,
);
@@ -199,6 +204,13 @@
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
+ C2525F462D7A22C100BD3CCA /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
C2E1C2D52CC9B5A400ADC565 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
@@ -209,6 +221,29 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
+ C2525F432D7A22C100BD3CCA /* TailscaleKit iOS */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C2525F4B2D7A22C100BD3CCA /* Build configuration list for PBXNativeTarget "TailscaleKit iOS" */;
+ buildPhases = (
+ C2525F462D7A22C100BD3CCA /* Headers */,
+ C2525F472D7A22C100BD3CCA /* Sources */,
+ C2525F482D7A22C100BD3CCA /* Frameworks */,
+ C2525F4A2D7A22C100BD3CCA /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ C2E1C2DC2CC9B5A400ADC565 /* TailscaleKit */,
+ );
+ name = "TailscaleKit iOS";
+ packageProductDependencies = (
+ );
+ productName = Tailscale;
+ productReference = C2525F4E2D7A22C100BD3CCA /* TailscaleKit.framework */;
+ productType = "com.apple.product-type.framework";
+ };
C28640612CCA8C9D00CD5EBC /* TailscaleKitTestHost */ = {
isa = PBXNativeTarget;
buildConfigurationList = C28640842CCA8C9E00CD5EBC /* Build configuration list for PBXNativeTarget "TailscaleKitTestHost" */;
@@ -231,9 +266,9 @@
productReference = C28640622CCA8C9D00CD5EBC /* TailscaleKitTestHost.app */;
productType = "com.apple.product-type.application";
};
- C2E1C2D92CC9B5A400ADC565 /* TailscaleKit */ = {
+ C2E1C2D92CC9B5A400ADC565 /* TailscaleKit macOS */ = {
isa = PBXNativeTarget;
- buildConfigurationList = C2E1C2ED2CC9B5A400ADC565 /* Build configuration list for PBXNativeTarget "TailscaleKit" */;
+ buildConfigurationList = C2E1C2ED2CC9B5A400ADC565 /* Build configuration list for PBXNativeTarget "TailscaleKit macOS" */;
buildPhases = (
C2E1C2D52CC9B5A400ADC565 /* Headers */,
C2E1C2D62CC9B5A400ADC565 /* Sources */,
@@ -243,12 +278,11 @@
buildRules = (
);
dependencies = (
- C2EE3B6A2CCBED1E00CF5BE0 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
C2E1C2DC2CC9B5A400ADC565 /* TailscaleKit */,
);
- name = TailscaleKit;
+ name = "TailscaleKit macOS";
packageProductDependencies = (
);
productName = Tailscale;
@@ -300,9 +334,6 @@
CreatedOnToolsVersion = 16.1;
TestTargetID = C28640612CCA8C9D00CD5EBC;
};
- C2EE3B622CCBE88400CF5BE0 = {
- CreatedOnToolsVersion = 16.1;
- };
};
};
buildConfigurationList = C2E1C2D42CC9B5A400ADC565 /* Build configuration list for PBXProject "TailscaleKit" */;
@@ -319,16 +350,23 @@
projectDirPath = "";
projectRoot = "";
targets = (
- C2E1C2D92CC9B5A400ADC565 /* TailscaleKit */,
+ C2E1C2D92CC9B5A400ADC565 /* TailscaleKit macOS */,
+ C2525F432D7A22C100BD3CCA /* TailscaleKit iOS */,
C2E1C30F2CCA8B7C00ADC565 /* TailscaleKitXCTests */,
C28640612CCA8C9D00CD5EBC /* TailscaleKitTestHost */,
- C2EE3B622CCBE88400CF5BE0 /* libtailscale */,
C2BED0552CCF3031004A2544 /* libtstestcontrol */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
+ C2525F4A2D7A22C100BD3CCA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
C28640602CCA8C9D00CD5EBC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -372,28 +410,16 @@
shellPath = /bin/sh;
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\npushd .\ncd $(SCROOT)/../tstestcontrol\nmake all\npopd\n";
};
- C2EE3B662CCBE88E00CF5BE0 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ C2525F472D7A22C100BD3CCA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
- inputFileListPaths = (
- );
- inputPaths = (
- );
- outputFileListPaths = (
- );
- outputPaths = (
- "$(SRCROOT)/../libtailscale.a",
- "$(SRCROOT)/../libtailscale.h",
- );
runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "# Type a script or drag a script file from your workspace to insert its path.\npushd .\ncd $(SCROOT)/..\nmake libtailscale\npopd\n";
};
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
C286405E2CCA8C9D00CD5EBC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -430,17 +456,110 @@
};
C2E1C3162CCA8B7C00ADC565 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = C2E1C2D92CC9B5A400ADC565 /* TailscaleKit */;
+ target = C2E1C2D92CC9B5A400ADC565 /* TailscaleKit macOS */;
targetProxy = C2E1C3152CCA8B7C00ADC565 /* PBXContainerItemProxy */;
};
- C2EE3B6A2CCBED1E00CF5BE0 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = C2EE3B622CCBE88400CF5BE0 /* libtailscale */;
- targetProxy = C2EE3B692CCBED1E00CF5BE0 /* PBXContainerItemProxy */;
- };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
+ C2525F4C2D7A22C100BD3CCA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
+ BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = W5364U7YZB;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_MODULE_VERIFIER = YES;
+ FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/..";
+ GENERATE_INFOPLIST_FILE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(SRCROOT)/..",
+ "$(SRCROOT)/TailscaleKit",
+ );
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 18.1;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = (
+ "@executable_path/../Frameworks",
+ "@loader_path/Frameworks",
+ );
+ LIBRARY_SEARCH_PATHS = "$(SRCROOT)/..";
+ MACOSX_DEPLOYMENT_TARGET = 15.0;
+ MARKETING_VERSION = 1.0;
+ MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
+ MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
+ PRODUCT_BUNDLE_IDENTIFIER = io.tailscale.Tailscale;
+ PRODUCT_MODULE_NAME = TailscaleKit;
+ PRODUCT_NAME = TailscaleKit;
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_INSTALL_OBJC_HEADER = NO;
+ SWIFT_VERSION = 6.0;
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ XROS_DEPLOYMENT_TARGET = 2.1;
+ };
+ name = Debug;
+ };
+ C2525F4D2D7A22C100BD3CCA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
+ BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DEVELOPMENT_TEAM = W5364U7YZB;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ ENABLE_MODULE_VERIFIER = YES;
+ FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/..";
+ GENERATE_INFOPLIST_FILE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(SRCROOT)/..",
+ "$(SRCROOT)/TailscaleKit",
+ );
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ IPHONEOS_DEPLOYMENT_TARGET = 18.1;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = (
+ "@executable_path/../Frameworks",
+ "@loader_path/Frameworks",
+ );
+ LIBRARY_SEARCH_PATHS = "$(SRCROOT)/..";
+ MACOSX_DEPLOYMENT_TARGET = 15.0;
+ MARKETING_VERSION = 1.0;
+ MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
+ MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
+ PRODUCT_BUNDLE_IDENTIFIER = io.tailscale.Tailscale;
+ PRODUCT_MODULE_NAME = TailscaleKit;
+ PRODUCT_NAME = TailscaleKit;
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_INSTALL_OBJC_HEADER = NO;
+ SWIFT_VERSION = 6.0;
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ XROS_DEPLOYMENT_TARGET = 2.1;
+ };
+ name = Release;
+ };
C28640852CCA8C9E00CD5EBC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -536,7 +655,7 @@
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/..",
- "$(SRCROOT)",
+ "$(SRCROOT)/TailscaleKit",
);
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -555,10 +674,11 @@
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
PRODUCT_BUNDLE_IDENTIFIER = io.tailscale.Tailscale;
- PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
- SDKROOT = auto;
+ PRODUCT_MODULE_NAME = TailscaleKit;
+ PRODUCT_NAME = TailscaleKit;
+ SDKROOT = macosx;
SKIP_INSTALL = YES;
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
+ SUPPORTED_PLATFORMS = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_VERSION = 6.0;
@@ -584,7 +704,7 @@
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = (
"$(SRCROOT)/..",
- "$(SRCROOT)",
+ "$(SRCROOT)/TailscaleKit",
);
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@@ -603,10 +723,11 @@
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
PRODUCT_BUNDLE_IDENTIFIER = io.tailscale.Tailscale;
- PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
- SDKROOT = auto;
+ PRODUCT_MODULE_NAME = TailscaleKit;
+ PRODUCT_NAME = TailscaleKit;
+ SDKROOT = macosx;
SKIP_INSTALL = YES;
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
+ SUPPORTED_PLATFORMS = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_VERSION = 6.0;
@@ -777,27 +898,18 @@
};
name = Release;
};
- C2EE3B642CCBE88400CF5BE0 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = W5364U7YZB;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Debug;
- };
- C2EE3B652CCBE88400CF5BE0 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = W5364U7YZB;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Release;
- };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ C2525F4B2D7A22C100BD3CCA /* Build configuration list for PBXNativeTarget "TailscaleKit iOS" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C2525F4C2D7A22C100BD3CCA /* Debug */,
+ C2525F4D2D7A22C100BD3CCA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
C28640842CCA8C9E00CD5EBC /* Build configuration list for PBXNativeTarget "TailscaleKitTestHost" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -825,7 +937,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- C2E1C2ED2CC9B5A400ADC565 /* Build configuration list for PBXNativeTarget "TailscaleKit" */ = {
+ C2E1C2ED2CC9B5A400ADC565 /* Build configuration list for PBXNativeTarget "TailscaleKit macOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C2E1C2EE2CC9B5A400ADC565 /* Debug */,
@@ -843,15 +955,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- C2EE3B632CCBE88400CF5BE0 /* Build configuration list for PBXAggregateTarget "libtailscale" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- C2EE3B642CCBE88400CF5BE0 /* Debug */,
- C2EE3B652CCBE88400CF5BE0 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
/* End XCConfigurationList section */
};
rootObject = C2E1C2D12CC9B5A400ADC565 /* Project object */;
diff --git a/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit (iOS).xcscheme b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit (iOS).xcscheme
new file mode 100644
index 0000000..f12fc73
--- /dev/null
+++ b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit (iOS).xcscheme
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit.xcscheme b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit (macOS).xcscheme
similarity index 94%
rename from swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit.xcscheme
rename to swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit (macOS).xcscheme
index 1c775c4..f13aa28 100644
--- a/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit.xcscheme
+++ b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/TailscaleKit (macOS).xcscheme
@@ -1,6 +1,6 @@
@@ -52,7 +52,7 @@
BuildableIdentifier = "primary"
BlueprintIdentifier = "C2E1C2D92CC9B5A400ADC565"
BuildableName = "TailscaleKit.framework"
- BlueprintName = "TailscaleKit"
+ BlueprintName = "TailscaleKit macOS"
ReferencedContainer = "container:TailscaleKit.xcodeproj">
diff --git a/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/libtailscale (ios).xcscheme b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/libtailscale (ios).xcscheme
new file mode 100644
index 0000000..9419789
--- /dev/null
+++ b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/libtailscale (ios).xcscheme
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/libtailscale (macOS).xcscheme b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/libtailscale (macOS).xcscheme
new file mode 100644
index 0000000..30f1c1c
--- /dev/null
+++ b/swift/TailscaleKit.xcodeproj/xcshareddata/xcschemes/libtailscale (macOS).xcscheme
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/swift/TailscaleKit/IncomingConnection.swift b/swift/TailscaleKit/IncomingConnection.swift
index 9a13ce6..b8cacb8 100644
--- a/swift/TailscaleKit/IncomingConnection.swift
+++ b/swift/TailscaleKit/IncomingConnection.swift
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: BSD-3-Clause
import Combine
+import Foundation
/// IncomingConnection is use to read incoming message from an inbound
/// connection. IncomingConnections are not instantiated directly,
diff --git a/swift/TailscaleKit/Listener.swift b/swift/TailscaleKit/Listener.swift
index c1d8d2f..89c1e83 100644
--- a/swift/TailscaleKit/Listener.swift
+++ b/swift/TailscaleKit/Listener.swift
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: BSD-3-Clause
import Combine
+import Foundation
/// A Listener is used to await incoming connections from another
/// Tailnet node.
diff --git a/swift/TailscaleKit/LogSink.swift b/swift/TailscaleKit/LogSink.swift
index 30931b4..73f45dd 100644
--- a/swift/TailscaleKit/LogSink.swift
+++ b/swift/TailscaleKit/LogSink.swift
@@ -1,6 +1,8 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
+import Foundation
+
/// A generic interface for sinking log messages from the Swift wrapper
/// and go
public protocol LogSink: Sendable {
@@ -13,19 +15,19 @@ public protocol LogSink: Sendable {
}
/// Dumps all internal logs to NSLog and go logs to stdout
-struct DefaultLogger: LogSink {
- var logFileHandle: Int32? = STDOUT_FILENO
+public struct DefaultLogger: LogSink {
+ public var logFileHandle: Int32? = STDOUT_FILENO
- func log(_ message: String) {
+ public func log(_ message: String) {
NSLog(message)
}
}
/// Discards all logs
-struct BlackholeLogger: LogSink {
- var logFileHandle: Int32?
-
- func log(_ message: String) {
+public struct BlackholeLogger: LogSink {
+ public var logFileHandle: Int32?
+
+ public func log(_ message: String) {
// Go back to the Shadow!
}
}
diff --git a/swift/TailscaleKit/OutgoingConnection.swift b/swift/TailscaleKit/OutgoingConnection.swift
index cca0f61..86d07c6 100644
--- a/swift/TailscaleKit/OutgoingConnection.swift
+++ b/swift/TailscaleKit/OutgoingConnection.swift
@@ -1,6 +1,7 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
+import Foundation
import Combine
/// ConnectionState indicates the state of individual TSConnection instances
diff --git a/swift/TailscaleKit/TailscaleError.swift b/swift/TailscaleKit/TailscaleError.swift
index 9cfe7eb..00dd274 100644
--- a/swift/TailscaleKit/TailscaleError.swift
+++ b/swift/TailscaleKit/TailscaleError.swift
@@ -1,6 +1,8 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
+import Foundation
+
public enum TailscaleError: Error {
case badInterfaceHandle ///< The tailscale handle is bad.
diff --git a/swift/TailscaleKit/TailscaleNode.swift b/swift/TailscaleKit/TailscaleNode.swift
index 7523ba5..b0d0875 100644
--- a/swift/TailscaleKit/TailscaleNode.swift
+++ b/swift/TailscaleKit/TailscaleNode.swift
@@ -1,15 +1,30 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
+public let kDefaultControlURL = "https://controlplane.tailscale.com"
+
+
/// Configuration for a tailscale application node
public struct Configuration: Sendable {
- let hostName: String ///< The hostname of the node/application instance
- let path: String
- let authKey: String? ///< An auth key. Leave empty to use web auth
- let controlURL: String ///< URL for Tailscale control
- let ephemeral: Bool
+ public let hostName: String ///< The hostname of the node/application instance
+ public let path: String
+ public let authKey: String? ///< An auth key. Leave empty to use web auth
+ public let controlURL: String ///< URL for Tailscale control
+ public let ephemeral: Bool
+
+ public init(hostName: String,
+ path: String,
+ authKey: String?,
+ controlURL: String,
+ ephemeral: Bool = false)
+ {
+ self.hostName = hostName
+ self.path = path
+ self.authKey = authKey
+ self.controlURL = controlURL
+ self.ephemeral = ephemeral
+ }
- static let defaultControlURL = "https://controlplane.tailscale.com"
}
/// The layer 3 protocol to use
diff --git a/swift/TailscaleKit/URLSession+Tailscale.swift b/swift/TailscaleKit/URLSession+Tailscale.swift
index 825b61f..349490b 100644
--- a/swift/TailscaleKit/URLSession+Tailscale.swift
+++ b/swift/TailscaleKit/URLSession+Tailscale.swift
@@ -1,8 +1,16 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
-extension URLSessionConfiguration {
+#if os(iOS)
+import UIKit
+#endif
+public extension URLSessionConfiguration {
+
+ // (barnstar) TODO: kCFNetworkProxiesSOCKS* is not available on iOS
+ // is there another way to make this work on non desktops?
+
+ #if os(macOS)
/// Adds the a connectionProxyDictionary to a URLSessionConfiguration to
/// proxy all requests through the given TailscaleNode.
///
@@ -28,10 +36,11 @@ extension URLSessionConfiguration {
]
}
- static func tailscaleSession(_ node: TailscaleNode) async throws -> URLSessionConfiguration {
+ public static func tailscaleSession(_ node: TailscaleNode) async throws -> URLSessionConfiguration {
let config = URLSessionConfiguration.default
try await config.proxyVia(node)
return config
}
+ #endif
}
diff --git a/swift/TailscaleKitXCTests/TailscaleKitTests.swift b/swift/TailscaleKitXCTests/TailscaleKitTests.swift
index bb3b7e1..7d543a5 100644
--- a/swift/TailscaleKitXCTests/TailscaleKitTests.swift
+++ b/swift/TailscaleKitXCTests/TailscaleKitTests.swift
@@ -171,7 +171,7 @@ final class TailscaleKitTests: XCTestCase {
let config = Configuration(hostName: "TSNet-Test",
path: temp,
authKey: authKey,
- controlURL: Configuration.defaultControlURL,
+ controlURL: kDefaultControlURL,
ephemeral: true)
let ts1 = try TailscaleNode(config: config, logger: logger)
diff --git a/swift/script/clangwrap.sh b/swift/script/clangwrap.sh
new file mode 100755
index 0000000..ff29975
--- /dev/null
+++ b/swift/script/clangwrap.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+
+SDK=iphoneos
+PLATFORM=ios
+
+CLANGARCH="arm64"
+
+SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
+
+# cmd/cgo doesn't support llvm-gcc-4.2, so we have to use clang.
+CLANG=`xcrun --sdk $SDK --find clang`
+
+exec "$CLANG" -arch $CLANGARCH -isysroot "$SDK_PATH" -m${PLATFORM}-version-min=12.0 "$@"