Skip to content

Commit a049b4f

Browse files
Start Data Connect Tools from Xcode (#60)
1 parent 8c012fa commit a049b4f

File tree

6 files changed

+368
-9
lines changed

6 files changed

+368
-9
lines changed

.github/workflows/spm.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ jobs:
7676
- name: Integration Test Setup
7777
run: Tests/Integration/Emulator/start-emulator.sh
7878
- name: Unit and Integration Tests
79-
run: scripts/third_party/travis/retry.sh ./scripts/build.sh FirebaseDataConnect ${{ matrix.target }} spm
79+
run: scripts/third_party/travis/retry.sh ./scripts/build.sh FirebaseDataConnect-Package ${{ matrix.target }} spm

Package.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ let package = Package(
2727
name: "FirebaseDataConnect",
2828
targets: ["FirebaseDataConnect"]
2929
),
30+
.executable(name: "Start FDC Tools", targets: ["SetupDevEnv"]),
3031
],
3132
dependencies: [
3233
firebaseDependency(),
@@ -53,6 +54,12 @@ let package = Package(
5354
],
5455
path: "Sources"
5556
),
57+
.target(name: "ShellExecutor", dependencies: [], path: "Tools/ShellExecutor"),
58+
.executableTarget(
59+
name: "SetupDevEnv",
60+
dependencies: ["ShellExecutor"],
61+
path: "Tools/SetupDevEnv"
62+
),
5663
.testTarget(
5764
name: "FirebaseDataConnectUnit",
5865
dependencies: ["FirebaseDataConnect"],
@@ -67,6 +74,11 @@ let package = Package(
6774
.copy("Resources/fdc-kitchensink"),
6875
]
6976
),
77+
.testTarget(
78+
name: "ShellExecutorTests",
79+
dependencies: ["ShellExecutor"],
80+
path: "Tests/ShellExecutor"
81+
),
7082
]
7183
)
7284

README.md

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,61 @@
11
# Firebase Data Connect iOS Open Source Development
22

3-
This repository contains the source code of Firebase Data Connect SDKs for development on iOS and other Apple platforms.
3+
This repository contains the source code of Firebase Data Connect Swift SDKs for development on iOS and other Apple platforms.
44

5-
Firebase Data Connect (https://firebase.google.com/products/data-connect) lets you build applications with CloudSQL for PostgreSQL
5+
Firebase Data Connect (https://firebase.google.com/docs/data-connect) lets you build applications with CloudSQL for PostgreSQL.
66

77
Firebase is an app development platform with tools to help you build, grow, and
88
monetize your app. More information about Firebase can be found on the
99
[official Firebase website](https://firebase.google.com).
1010

11-
## Getting Started
11+
## Installation
1212

13-
Learn how to develop on Data Connect - [Quick Start](https://firebase.google.com/docs/data-connect/quickstart).
13+
This process shows you how to setup Firebase Data Connect tools with Xcode.
1414

15-
Try out a comprehensive sample app - [FriendlyFlix](https://github.com/firebase/data-connect-ios-sdk/tree/main/Examples/FriendlyFlix)
15+
* Get the Firebase Data Connect iOS SDK.
16+
```
17+
git clone https://github.com/firebase/data-connect-ios-sdk.git
18+
```
19+
* Add it as a local package dependency in your Xcode project
20+
* From your Xcode project, select `File -> Add Package Dependencies -> Add Local`.
21+
* Select the `data-connect-ios-sdk` folder containing the cloned SDK.
22+
* Add `FirebaseDataConnect` to your app target.
23+
* Add and Edit Xcode Scheme
24+
* From your list of schemes, select `New Scheme`.
25+
* Xcode should show you `Start FDC Tools` as a potential scheme. Select that.
26+
* Adjust working directory
27+
* Edit the `Start FDC Tools` Scheme from `Edit Scheme... -> Start FDC Tools`.
28+
* Go to `Run -> Options -> Working Directory`
29+
* Select `Custom working directory` and pick your Xcode project folder
30+
* This ensures that Firebase Data Connect tools start in the correct folder each time.
31+
* Run the `Start FDC Tools` target selecting `My Mac` as the device.
32+
* This should start the tools in a separate browser window (or tab).
33+
* Now that you have the tools, try out our [Codelab](https://firebase.google.com/codelabs/firebase-dataconnect-ios#0)
34+
* Learn more about designing schemas, queries and mutations - [Design Schemas](https://firebase.google.com/docs/data-connect/schemas-guide)
1635
17-
## Installation
36+
* Generated SDKs are Swift packages. Add the generated SDKs to your project as a Local Package dependency and start using them in your app.
37+
* Generated APIs support `@Observable` (Observation framework) for easy integration into SwiftUI apps.
38+
* UIKit apps can make use of the underlying `Combine` publishers.
39+
* All Query and Mutation APIs are `async` calls and can participate in Swift concurrency.
40+
* Since you cloned the `data-connect-ios-sdk`, be sure to reference your local folder to generate SDKs.
41+
* In the `connector.yaml`, configure the Swift SDK generation to point to the local path where you cloned the Data Connect iOS SDK using the `coreSdkPackageLocation` parameter. Example -
42+
```yaml
43+
generate:
44+
swiftSdk:
45+
outputDir: ../../dataconnect-generated/swift
46+
package: DefaultConnector #change this to your project specific name
47+
coreSdkPackageLocation: /Users/abc/Code/data-connect-ios-sdk
48+
```
1849
19-
The Data Connect SDK should get automatically added as a dependency if you use generated SDKs. However, if you need to add it manually, use the following instructions for Swift Package Manager.
50+
There are other paths to get setup with Firebase Data Connect tools such as from the Firebase Console. To learn more visit - [Quick Start](https://firebase.google.com/docs/data-connect/quickstart).
2051
21-
### Swift Package Manager
52+
## Sample App and Code Lab
2253
54+
* [Codelab](https://firebase.google.com/codelabs/firebase-dataconnect-ios#0)
55+
56+
* Comprehensive Sample app - [FriendlyFlix](https://github.com/firebase/data-connect-ios-sdk/tree/main/Examples/FriendlyFlix)
57+
58+
### Swift Package Manager
2359
Instructions for [Swift Package Manager](https://swift.org/package-manager/) support can be
2460
found in the [SwiftPackageManager.md](SwiftPackageManager.md) Markdown file.
2561
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import XCTest
16+
17+
#if os(macOS)
18+
@testable import ShellExecutor
19+
20+
@available(macOS 12.0, *)
21+
final class ShellExecutorTests: XCTestCase {
22+
var executor: ShellExecutor!
23+
24+
override func setUp() {
25+
super.setUp()
26+
// This is run before each test
27+
executor = ShellExecutor()
28+
}
29+
30+
/// Tests that a simple, successful command completes without throwing a Swift error.
31+
func testSuccessfulCommand() {
32+
// The `true` command does nothing and exits with status 0.
33+
XCTAssertNoThrow(
34+
try executor.run("true"),
35+
"A successful command should not throw an error."
36+
)
37+
}
38+
39+
/// Tests that a failing command completes without throwing a Swift error,
40+
/// as our function handles the non-zero exit code internally.
41+
func testFailingCommand() {
42+
// The `false` command does nothing and exits with status 1.
43+
XCTAssertNoThrow(
44+
try executor.run("false"),
45+
"A failing command should be handled gracefully, not throw."
46+
)
47+
}
48+
49+
/// Tests if the standard output from the command is correctly captured and printed.
50+
func testStandardOutputCapture() throws {
51+
let testString = "Hello from XCTest!"
52+
let command = "echo '\(testString)'"
53+
54+
// We need to capture the process's stdout to verify it.
55+
// This is a common pattern for testing command-line output.
56+
let outputPipe = Pipe()
57+
58+
// Save the original standard output file handle
59+
let originalStdout = dup(STDOUT_FILENO)
60+
61+
// Redirect stdout to our pipe's write end
62+
dup2(outputPipe.fileHandleForWriting.fileDescriptor, STDOUT_FILENO)
63+
64+
// Run the command. Its output will go into the pipe.
65+
try executor.run(command)
66+
67+
// Close the write end of the pipe to signal end-of-file
68+
try outputPipe.fileHandleForWriting.close()
69+
70+
// Restore the original standard output
71+
dup2(originalStdout, STDOUT_FILENO)
72+
close(originalStdout)
73+
74+
// Read all data from the pipe
75+
let capturedData = outputPipe.fileHandleForReading.readDataToEndOfFile()
76+
let capturedOutput = String(data: capturedData, encoding: .utf8) ?? ""
77+
78+
XCTAssertTrue(
79+
capturedOutput.contains(testString),
80+
"The captured output should contain the test string '\(testString)'"
81+
)
82+
83+
XCTAssertTrue(
84+
capturedOutput.contains("✅ ShellExecutor: Command finished successfully."),
85+
"The output should contain the success message."
86+
)
87+
}
88+
}
89+
#endif
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import Foundation
16+
17+
import ShellExecutor
18+
19+
// port on which FDC tools (code-server) listen
20+
let FDC_TOOLS_PORT: UInt = 9394
21+
22+
@available(macOS 12.0, *)
23+
@main
24+
struct SetupDevEnv {
25+
static func main() {
26+
#if os(macOS)
27+
let currentDirectoryPath = FileManager.default.currentDirectoryPath
28+
print("Attempting to start Data Connect Tools in Directory: \(currentDirectoryPath)")
29+
30+
let executor = ShellExecutor()
31+
32+
do {
33+
// When the `Start FDC Tools` process is stopped from Xcode,
34+
// it still leaves an orphaned code-server process since SIGKILL isn't received by the
35+
// command line utility
36+
try executor.killProcessOnPort(FDC_TOOLS_PORT)
37+
} catch {
38+
print("❌ Error killing process \(error)")
39+
}
40+
41+
do {
42+
let commandToRun = "curl -sL https://firebase.tools/dataconnect | bash"
43+
try executor.run(commandToRun)
44+
} catch {
45+
print("❌ Error running command: \(error)")
46+
}
47+
#endif // if macos
48+
}
49+
}

0 commit comments

Comments
 (0)