Skip to content

Commit 8d8ba6f

Browse files
authored
FetchDeviceOperation: account for pagination (#91)
- Always try to register the device and just return gracefully if it fails (prevents races, pagination issues) - Allow `SigningContext` (and therefore `AutoSigner`) to be created without a target device: just skip device registration.
1 parent 72db71c commit 8d8ba6f

5 files changed

Lines changed: 49 additions & 51 deletions

File tree

Sources/XKit/DeveloperServices/DeveloperServicesProvisioningOperation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public struct DeveloperServicesProvisioningOperation: DeveloperServicesOperation
3939

4040
public func perform() async throws -> Response {
4141
progress(0/3)
42-
_ = try await DeveloperServicesFetchDeviceOperation(context: context).perform()
42+
try await DeveloperServicesAddDeviceOperation(context: context).perform()
4343

4444
progress(1/3)
4545
let signingInfo = try await DeveloperServicesFetchCertificateOperation(
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Foundation
2+
import DeveloperAPI
3+
4+
public struct DeveloperServicesAddDeviceOperation: DeveloperServicesOperation {
5+
public let context: SigningContext
6+
public init(context: SigningContext) {
7+
self.context = context
8+
}
9+
10+
public func perform() async throws {
11+
guard let targetDevice = context.targetDevice else { return }
12+
13+
// try to register the device
14+
let response = try await context.developerAPIClient.devicesCreateInstance(
15+
body: .json(.init(data: .init(
16+
_type: .devices,
17+
attributes: .init(
18+
name: targetDevice.name,
19+
platform: .init(.ios),
20+
udid: targetDevice.udid
21+
)
22+
)))
23+
)
24+
25+
// we get a 409 CONFLICT if the device was already registered.
26+
// handle this by returning gracefully.
27+
if (try? response.conflict) != nil {
28+
return
29+
}
30+
31+
// otherwise, we should get a 201 CREATED to indicate that the device
32+
// was added. any other case is unexpected, and this will throw.
33+
_ = try response.created
34+
}
35+
36+
}

Sources/XKit/DeveloperServices/Devices/DeveloperServicesFetchDeviceOperation.swift

Lines changed: 0 additions & 39 deletions
This file was deleted.

Sources/XKit/Integration/IntegratedInstaller.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,8 @@ public actor IntegratedInstaller {
270270
try await updateProgress(to: 1)
271271

272272
let context = try SigningContext(
273-
udid: udid,
274-
deviceName: deviceName,
275-
auth: auth
273+
auth: auth,
274+
targetDevice: .init(udid: udid, name: deviceName)
276275
)
277276

278277
let signer = AutoSigner(context: context) { certs in

Sources/XKit/Signer/SigningContext.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,26 @@ import DeveloperAPI
1111

1212
public struct SigningContext: Sendable {
1313

14-
public let udid: String
15-
public let deviceName: String
16-
public let auth: DeveloperAPIAuthData
17-
public let signer: Signer
14+
public struct TargetDevice: Sendable, Hashable {
15+
public var udid: String
16+
public var name: String
17+
}
18+
19+
public var auth: DeveloperAPIAuthData
20+
public var targetDevice: TargetDevice?
21+
public var signer: Signer
1822

1923
public var developerAPIClient: DeveloperAPIClient {
2024
DeveloperAPIClient(auth: auth)
2125
}
2226

2327
public init(
24-
udid: String,
25-
deviceName: String,
2628
auth: DeveloperAPIAuthData,
29+
targetDevice: TargetDevice? = nil,
2730
signer: Signer? = nil
2831
) throws {
29-
self.udid = udid
30-
self.deviceName = deviceName
3132
self.auth = auth
33+
self.targetDevice = targetDevice
3234
self.signer = try signer ?? .first()
3335
}
3436

0 commit comments

Comments
 (0)