Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Use Swift-Bridge generated files with libxmtp XCFramework to run gRPC query #1

Merged
merged 7 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions Cargo.toml

This file was deleted.

32 changes: 0 additions & 32 deletions Makefile

This file was deleted.

16 changes: 13 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
// swift-tools-version:5.3
import PackageDescription
import Foundation

let package = Package(
name: "XMTPRustSwift",
name: "XMTPRust",
platforms: [
.iOS(.v13),
.macOS(.v11)
],
products: [
.library(
name: "XMTPRustSwift",
targets: ["XMTPRustSwift"]),
name: "XMTPRust",
targets: ["XMTPRust", "XMTPRustSwift"]),
],
targets: [
.target(
name: "XMTPRust",
dependencies: ["XMTPRustSwift"],
path: "Sources/XMTPRust"
),
.binaryTarget(
name: "XMTPRustSwift",
path: "XMTPRustSwift.xcframework"),
.testTarget(
name: "XMTPRust-Tests",
dependencies: ["XMTPRust"],
path: "Tests/XMTPRust-Tests")
]
)
84 changes: 84 additions & 0 deletions Sources/XMTPRust/ApiService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// ApiService.swift
//
//
// Created by Michael Xu on 4/14/23.
//

import Foundation

// The goal of this class is to provide a steady-ish Swift interface between Rust and xmtp-ios
public class ApiService {
static let shared = ApiService()

let environment: String
let secure: Bool

public init(environment: String = "https://dev.xmtp.network", secure: Bool = true) {
self.environment = environment
self.secure = secure
}

// shared getter
public static func get() -> ApiService {
return ApiService.shared
}
Comment on lines +22 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swifty-ness would say we don't need this getter since we've already got ApiService.shared, we could just make that public.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah good call!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix for future releases


// It's all strings all the time
public func query(topic: String, json_paging_info: String) async throws -> String {
// Call XMTPRust.query_serialized with the given parameters, expect a XMTPRust.ResponseJson object
// that has { error: String, json: String }
let response: ResponseJson = await XMTPRust.query(self.environment.intoRustString(), topic.intoRustString(), json_paging_info.intoRustString())

// If the error is not an empty string
if response.error.toString() != "" {
throw NSError(domain: "XMTPRust", code: 0, userInfo: [NSLocalizedDescriptionKey: response.error.toString()])
}

return response.json.toString()
}

// Publishes a string, which better be an encoded Xmtp_MessageApi_V1_PublishRequest with envelopes provided
public func publish(token: String, envelopes: String) async throws -> String {
// Call XMTPRust.publish_serialized with the given parameters, expect a XMTPRust.ResponseJson object
// that has { error: String, json: String }
let response: ResponseJson = await XMTPRust.publish(self.environment.intoRustString(), token.intoRustString(), envelopes.intoRustString())

// If the error is not an empty string
if response.error.toString() != "" {
throw NSError(domain: "XMTPRust", code: 0, userInfo: [NSLocalizedDescriptionKey: response.error.toString()])
}

return response.json.toString()
}

// Subscribe, we need to fake an AsyncThrowingStream by cleverly using a DispatchQueue and repeatedly
// calling an async function that will call XMTPRust.subscribe_serialized and return a string
// that better be an encoded Xmtp_MessageApi_V1_SubscribeResponse with envelopes provided
func subscribe(topics: [String]) -> AsyncThrowingStream<String, Error> {
return AsyncThrowingStream { continuation in
// Create a DispatchQueue
let queue = DispatchQueue(label: "XMTPRust.subscribe_serialized")
// Run a constant for loop that calls subscribe_once over and over
queue.async {
Task {
let vec = RustVec<RustString>()
for topic in topics {
vec.push(value: topic.intoRustString())
}
// Call XMTPRust.subscribe_serialized with the given parameters, expect a String
// that better be an encoded Xmtp_MessageApi_V1_SubscribeResponse with envelopes provided
let response = await XMTPRust.subscribe_once(self.environment.intoRustString(), vec)

// If the error is not an empty string
if response.error.toString() != "" {
continuation.finish(throwing: NSError(domain: "XMTPRust", code: 0, userInfo: [NSLocalizedDescriptionKey: response.error.toString()]))
}

// Yield the response
continuation.yield(response.json.toString())
}
}
}
}
}
Loading