Skip to content

Commit 39fccbf

Browse files
committed
Migrate to swift 6.0 & swift-gRPC 2.0
The following migrates to swift 6.0, and also migrate to swift-grpc 2.0 that uses swift-nio under the hood to provide nicer API and async await
1 parent 4e582b0 commit 39fccbf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2460
-929
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ jobs:
495495
name: Test Swift Linux
496496
strategy:
497497
matrix:
498-
swift: ["5.10", "6.1", "6.2"]
498+
swift: ["6.0", "6.1", "6.2"]
499499
runs-on: ubuntu-24.04
500500
steps:
501501
- uses: actions/checkout@v6

Package.swift

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.10
1+
// swift-tools-version:6.0
22
/*
33
* Copyright 2020 Google Inc. All rights reserved.
44
*
@@ -36,14 +36,17 @@ let package = Package(
3636
.target(
3737
name: "FlatBuffers",
3838
dependencies: ["Common"],
39-
path: "swift/Sources/FlatBuffers"),
39+
path: "swift/Sources/FlatBuffers",
40+
swiftSettings: .settings),
4041
.target(
4142
name: "FlexBuffers",
4243
dependencies: ["Common"],
43-
path: "swift/Sources/FlexBuffers"),
44+
path: "swift/Sources/FlexBuffers",
45+
swiftSettings: .settings),
4446
.target(
4547
name: "Common",
46-
path: "swift/Sources/Common"),
48+
path: "swift/Sources/Common",
49+
swiftSettings: .settings),
4750
.testTarget(
4851
name: "FlatbuffersTests",
4952
dependencies: .dependencies,
@@ -52,15 +55,27 @@ let package = Package(
5255
name: "FlexbuffersTests",
5356
dependencies: ["FlexBuffers"],
5457
path: "tests/swift/Tests/Flexbuffers"),
55-
])
58+
],
59+
swiftLanguageModes: [.v6])
60+
61+
extension Array where Element == SwiftSetting {
62+
static var settings: [SwiftSetting] {
63+
[.enableUpcomingFeature("ExistentialAny")]
64+
}
65+
}
5666

5767
extension Array where Element == Package.Dependency {
5868
static var dependencies: [Package.Dependency] {
5969
#if os(Windows)
6070
[]
6171
#else
6272
// Test only Dependency
63-
[.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.4.1")]
73+
[
74+
.package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.0.0"),
75+
.package(
76+
url: "https://github.com/grpc/grpc-swift-nio-transport.git",
77+
from: "2.0.0"),
78+
]
6479
#endif
6580
}
6681
}
@@ -72,7 +87,10 @@ extension Array where Element == PackageDescription.Target.Dependency {
7287
#else
7388
// Test only Dependency
7489
[
75-
.product(name: "GRPC", package: "grpc-swift"),
90+
.product(name: "GRPCCore", package: "grpc-swift-2"),
91+
.product(
92+
name: "GRPCNIOTransportHTTP2",
93+
package: "grpc-swift-nio-transport"),
7694
"FlatBuffers",
7795
]
7896
#endif

grpc/examples/greeter_v2.fbs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace models;
2+
3+
table HelloResponse {
4+
message:string;
5+
}
6+
7+
table HelloRequest {
8+
name:string;
9+
}
10+
11+
rpc_service Greeter {
12+
Get(HelloRequest):HelloResponse;
13+
Collect(HelloRequest):HelloResponse (streaming: "client");
14+
Expand(HelloRequest):HelloResponse (streaming: "server");
15+
Update(HelloRequest):HelloResponse (streaming: "bidi");
16+
}
Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.10
1+
// swift-tools-version:6.2
22
/*
33
* Copyright 2020 Google Inc. All rights reserved.
44
*
@@ -20,39 +20,43 @@ import PackageDescription
2020
let package = Package(
2121
name: "Greeter",
2222
platforms: [
23-
.iOS(.v12),
24-
.macOS(.v10_14),
23+
.iOS(.v18),
24+
.macOS(.v15),
2525
],
2626
dependencies: [
27-
.package(path: "../../../../swift"),
28-
.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"),
27+
.package(path: "../../../.."),
28+
.package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.0.0"),
29+
.package(
30+
url: "https://github.com/grpc/grpc-swift-nio-transport.git",
31+
from: "2.0.0"),
32+
.package(
33+
url: "https://github.com/apple/swift-argument-parser.git",
34+
from: "1.5.0"),
2935
],
3036
targets: [
3137
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
3238
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
3339
.target(
34-
name: "Model",
40+
name: "Models",
3541
dependencies: [
36-
"GRPC",
37-
"FlatBuffers",
38-
],
39-
path: "Sources/Model"),
42+
.product(name: "FlatBuffers", package: "flatbuffers"),
43+
.product(name: "GRPCCore", package: "grpc-swift-2"),
44+
.product(
45+
name: "GRPCNIOTransportHTTP2",
46+
package: "grpc-swift-nio-transport"),
47+
]),
4048

4149
// Client for the Greeter example
42-
.target(
43-
name: "Client",
44-
dependencies: [
45-
"GRPC",
46-
"Model",
47-
],
48-
path: "Sources/client"),
49-
50-
// Server for the Greeter example
51-
.target(
52-
name: "Server",
50+
.executableTarget(
51+
name: "Commands",
5352
dependencies: [
54-
"GRPC",
55-
"Model",
56-
],
57-
path: "Sources/server"),
53+
.product(name: "GRPCCore", package: "grpc-swift-2"),
54+
.product(
55+
name: "GRPCNIOTransportHTTP2",
56+
package: "grpc-swift-nio-transport"),
57+
.product(
58+
name: "ArgumentParser",
59+
package: "swift-argument-parser"),
60+
"Models",
61+
]),
5862
])
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2024 Google Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import ArgumentParser
18+
19+
let port = 3000
20+
21+
@main
22+
struct GreeterCommand: AsyncParsableCommand {
23+
static let configuration = CommandConfiguration(
24+
commandName: "greeter",
25+
abstract: "A multi-tool to run an echo server and execute RPCs against it.",
26+
subcommands: [ServerCommand.self, ClientCommand.self])
27+
}
28+
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright 2024 Google Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import FlatBuffers
18+
import GRPCCore
19+
import Models
20+
21+
struct GreeterService: models_Greeter.SimpleServiceProtocol {
22+
func Get(
23+
request: GRPCMessage<models_HelloResponse>,
24+
context: GRPCCore
25+
.ServerContext) async throws -> GRPCMessage<models_HelloResponse>
26+
{
27+
let model = try request.decode()
28+
print("## GreeterService.Get: \(model.message)")
29+
30+
var builder = FlatBufferBuilder(initialSize: 128)
31+
let off = builder.create(string: "Hello \(model.message ?? "Unknown")")
32+
let root = models_HelloResponse.createHelloResponse(
33+
&builder,
34+
messageOffset: off)
35+
builder.finish(offset: root)
36+
return try GRPCMessage<models_HelloResponse>(builder: &builder)
37+
}
38+
39+
func Collect(
40+
request: GRPCCore.RPCAsyncSequence<
41+
GRPCMessage<models_HelloResponse>,
42+
any Swift.Error
43+
>,
44+
context: GRPCCore
45+
.ServerContext) async throws -> GRPCMessage<models_HelloResponse>
46+
{
47+
let messages: [String] = try await request
48+
.reduce(into: []) { array, message in
49+
let model = try message.decode()
50+
return array.append(model.message ?? "Unknown")
51+
}
52+
53+
let joined = messages.joined(separator: ", ")
54+
print("## GreeterService.Collect: \(joined)")
55+
56+
var builder = FlatBufferBuilder(initialSize: 128)
57+
let off = builder.create(string: "Hello \(joined)")
58+
let root = models_HelloResponse.createHelloResponse(
59+
&builder,
60+
messageOffset: off)
61+
builder.finish(offset: root)
62+
return try GRPCMessage<models_HelloResponse>(builder: &builder)
63+
}
64+
65+
func Expand(
66+
request: GRPCMessage<models_HelloResponse>,
67+
response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
68+
context: GRPCCore.ServerContext) async throws
69+
{
70+
71+
let model = try request.decode()
72+
print("## GreeterService.Expand: \(model.message)")
73+
74+
let message = model.message ?? "Unknown"
75+
let stream = AsyncThrowingStream<
76+
GRPCMessage<models_HelloResponse>,
77+
Error
78+
> { continuation in
79+
var builder = FlatBufferBuilder(initialSize: 128)
80+
for char in message {
81+
let off = builder.create(string: "\(char)")
82+
let root = models_HelloResponse.createHelloResponse(
83+
&builder,
84+
messageOffset: off)
85+
builder.finish(offset: root)
86+
87+
do {
88+
continuation
89+
.yield(try GRPCMessage<models_HelloResponse>(builder: &builder))
90+
} catch {
91+
continuation.finish(throwing: error)
92+
}
93+
}
94+
95+
continuation.finish()
96+
}
97+
try await response.write(contentsOf: stream)
98+
}
99+
100+
func Update(
101+
request: GRPCCore.RPCAsyncSequence<
102+
GRPCMessage<models_HelloResponse>,
103+
any Swift.Error
104+
>,
105+
response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
106+
context: GRPCCore.ServerContext) async throws
107+
{
108+
for try await message in request {
109+
let model = try message.decode()
110+
print("## GreeterService.Update: \(model.message)")
111+
var builder = FlatBufferBuilder(initialSize: 128)
112+
let off = builder.create(string: "Hello \(model.message ?? "Unknown")")
113+
let root = models_HelloResponse.createHelloResponse(
114+
&builder,
115+
messageOffset: off)
116+
builder.finish(offset: root)
117+
try await response
118+
.write(try GRPCMessage<models_HelloResponse>(builder: &builder))
119+
}
120+
}
121+
}

0 commit comments

Comments
 (0)