Skip to content
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
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,13 @@ local.properties

# Ignore generated jni libs - at least for now
./native/android/lib/src/main/jniLibs

# macOS
.DS_Store

# Swift
.build
.swiftpm/xcode

# Auto-generated Swift Files
native/swift/Sources/wordpress-api-wrapper/*.swift
6 changes: 6 additions & 0 deletions .swiftpm/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module libwordpressFFI {
header "wp_apiFFI.h"
header "wp_networkingFFI.h"
header "wp_parsingFFI.h"
export *
}
132 changes: 127 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ docker_container_repo_dir=/app
docker_opts_shared := --rm -v "$(PWD)":$(docker_container_repo_dir) -w $(docker_container_repo_dir)
docker_build_and_run := docker build -t foo . && docker run $(docker_opts_shared) -it foo

clean:
git clean -ffxd

_generate-jni-libs:
rm -rf $(jni_libs_root)
cargo build --release --lib --target x86_64-linux-android --target i686-linux-android --target armv7-linux-androideabi --target aarch64-linux-android
Expand All @@ -22,21 +25,140 @@ _generate-jni-libs:
cp ./target/i686-linux-android/release/libwp_api.so $(jni_libs_root)/x86/libuniffi_wp_api.so
cp ./target/x86_64-linux-android/release/libwp_api.so $(jni_libs_root)/x86_64/libuniffi_wp_api.so

_generate-bindings:
rm -rf $(android_generated_source_path)
bindings:
rm -rf $(android_generated_source_path) target/swift-bindings
cargo build --release

#wp_api
cargo run --release --bin uniffi_bindgen generate --library ./target/release/libwp_api.dylib --out-dir $(android_generated_source_path) --language kotlin
cargo run --release --bin uniffi_bindgen generate wp_api/src/wp_api.udl --out-dir ./target/swift-bindings --language swift
cp target/swift-bindings/wp_api.swift native/swift/Sources/wordpress-api-wrapper/wp_api.swift
sed -i '' 's/wp_apiFFI/libwordpressFFI/g' native/swift/Sources/wordpress-api-wrapper/wp_api.swift

#wp_networking
cargo run --release --bin uniffi_bindgen generate --library ./target/release/libwp_networking.dylib --out-dir $(android_generated_source_path) --language kotlin
cargo run --release --bin uniffi_bindgen generate wp_networking/src/wp_networking.udl --out-dir ./target/swift-bindings --language swift
cp target/swift-bindings/wp_networking.swift native/swift/Sources/wordpress-api-wrapper/wp_networking.swift
sed -i '' 's/wp_networkingFFI/libwordpressFFI/g' native/swift/Sources/wordpress-api-wrapper/wp_networking.swift

#wp_parsing
cargo run --release --bin uniffi_bindgen generate --library ./target/release/libwp_parsing.dylib --out-dir $(android_generated_source_path) --language kotlin
cargo run --release --bin uniffi_bindgen generate wp_parsing/src/wp_parsing.udl --out-dir ./target/swift-bindings --language swift
cp target/swift-bindings/wp_parsing.swift native/swift/Sources/wordpress-api-wrapper/wp_parsing.swift
sed -i '' 's/wp_parsingFFI/libwordpressFFI/g' native/swift/Sources/wordpress-api-wrapper/wp_parsing.swift

_test-android:
./native/android/gradlew -p ./native/android cAT

_publish-android-local:
./native/android/gradlew -p ./native/android publishToMavenLocal -exclude-task prepareToPublishToS3

test-android: _generate-bindings _test-android

publish-android-local: _generate-bindings _publish-android-local
# Builds the library for all the various architectures / systems required in an XCFramework
xcframework-libraries:
# macOS
$(MAKE) x86_64-apple-darwin-xcframework-library
$(MAKE) aarch64-apple-darwin-xcframework-library

# iOS
$(MAKE) aarch64-apple-ios-xcframework-library
$(MAKE) x86_64-apple-ios-xcframework-library
$(MAKE) aarch64-apple-ios-sim-xcframework-library

# tvOS
$(MAKE) aarch64-apple-tvos-xcframework-library-with-nightly
$(MAKE) aarch64-apple-tvos-sim-xcframework-library-with-nightly
$(MAKE) x86_64-apple-tvos-xcframework-library-with-nightly

# watchOS
$(MAKE) arm64_32-apple-watchos-xcframework-library-with-nightly
$(MAKE) aarch64-apple-watchos-sim-xcframework-library-with-nightly
$(MAKE) x86_64-apple-watchos-sim-xcframework-library-with-nightly

%-xcframework-library:
cargo build --target $* --release
$(MAKE) $*-combine-libraries

%-xcframework-library-with-nightly:
cargo +nightly build --target $* --release -Zbuild-std
$(MAKE) $*-combine-libraries

# Xcode doesn't properly support multiple XCFrameworks being used by the same target, so we need
# to combine the binaries
%-combine-libraries:
xcrun libtool -static -o target/$*/release/libwordpress.a target/$*/release/libwp_api.a target/$*/release/libwp_networking.a target/$*/release/libwp_parsing.a

# Some libraries need to be created in a multi-binary format, so we combine them here
xcframework-combined-libraries: xcframework-libraries

rm -rf target/universal-*
mkdir -p target/universal-macos/release target/universal-ios/release target/universal-tvos/release target/universal-watchos/release

# Combine the macOS Binaries
lipo -create target/aarch64-apple-darwin/release/libwordpress.a target/x86_64-apple-darwin/release/libwordpress.a \
-output target/universal-macos/release/libwordpress.a
lipo -info target/universal-macos/release/libwordpress.a

# Combine iOS Simulator Binaries
lipo -create target/aarch64-apple-ios-sim/release/libwordpress.a target/x86_64-apple-ios/release/libwordpress.a \
-output target/universal-ios/release/libwordpress.a
lipo -info target/universal-ios/release/libwordpress.a

# Combine tvOS Simulator Binaries
lipo -create target/aarch64-apple-tvos-sim/release/libwordpress.a target/x86_64-apple-tvos/release/libwordpress.a \
-output target/universal-tvos/release/libwordpress.a
lipo -info target/universal-tvos/release/libwordpress.a

# Combine watchOS Simulator Binaries
lipo -create target/aarch64-apple-watchos-sim/release/libwordpress.a target/x86_64-apple-watchos-sim/release/libwordpress.a \
-output target/universal-watchos/release/libwordpress.a
lipo -info target/universal-watchos/release/libwordpress.a

# An XCFramework relies on the .h file and the modulemap to interact with the precompiled binary
xcframework-headers: bindings
rm -rvf target/swift-bindings/headers
mkdir -p target/swift-bindings/headers

mv target/swift-bindings/*.h target/swift-bindings/headers
cp .swiftpm/module.modulemap target/swift-bindings/headers/module.modulemap

# Generate the xcframework
#
# Requires the following runtimes:
# rustup target add x86_64-apple-ios
# rustup target add aarch64-apple-ios
# rustup target add aarch64-apple-darwin
# rustup target add x86_64-apple-darwin
# rustup target add aarch64-apple-ios-sim
#
# rustup toolchain install nightly
# rustup component add rust-src --toolchain nightly-aarch64-apple-darwin
xcframework: bindings xcframework-combined-libraries xcframework-headers

rm -rf target/libwordpressFFI.xcframework

xcodebuild -create-xcframework \
-library target/aarch64-apple-ios/release/libwordpress.a \
-headers target/swift-bindings/headers \
-library target/universal-macos/release/libwordpress.a \
-headers target/swift-bindings/headers \
-library target/universal-ios/release/libwordpress.a \
-headers target/swift-bindings/headers \
-library target/aarch64-apple-tvos/release/libwordpress.a \
-headers target/swift-bindings/headers \
-library target/universal-tvos/release/libwordpress.a \
-headers target/swift-bindings/headers \
-library target/universal-watchos/release/libwordpress.a \
-headers target/swift-bindings/headers \
-output target/libwordpressFFI.xcframework

test-swift: xcframework
swift test

test-android: bindings _test-android

publish-android-local: bindings _publish-android-local

build-in-docker:
$(call _generate-bindings)
$(call bindings)
$(docker_build_and_run)
49 changes: 49 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
// Swift Package: WordpressApi

import PackageDescription

let package = Package(
name: "wordpress",
platforms: [
.iOS(.v13),
.macOS(.v10_15),
.tvOS(.v13),
.watchOS(.v8)
],
products: [
.library(
name: "wordpress-api",
targets: ["wordpress-api"]
)
],
dependencies: [],
targets: [
.target(
name: "wordpress-api",
dependencies: [
.target(name: "wordpress-api-wrapper"),
],
path: "native/swift/Sources/wordpress-api"
),
.testTarget(
name: "wordpress-api-tests",
dependencies: [
.target(name: "wordpress-api")
],
path: "native/swift/Tests/wordpress-api"
),
.target(
name: "wordpress-api-wrapper",
dependencies: [
.target(name: "libwordpressFFI")
],
path: "native/swift/Sources/wordpress-api-wrapper",
exclude: [
"README.md"
]
),
.binaryTarget(name: "libwordpressFFI", path: "target/libwordpressFFI.xcframework"),
]
)
3 changes: 3 additions & 0 deletions native/swift/Sources/wordpress-api-wrapper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# wordpress-api-wrapper

The contents of this directory are auto-generated by Rust and uniffi – you should not try to change them manually!
30 changes: 30 additions & 0 deletions native/swift/Sources/wordpress-api/WordPressAPI.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Foundation

import wordpress_api_wrapper

public struct WordPressAPI {

private let parser: PostResponseParser

public init(parser: PostResponseParser = postResponseParser()) {
self.parser = parser
}

public func listPosts(params: PostListParams = .default) async throws -> ParsedPostListResponse {
let request = PostRequestBuilder().list(params: params) // TODO: Get the request stuff over into a `URLRequest`

let _request = URLRequest(url: URL(string: "https://public-api.wordpress.com")!)
let (data, response) = try await URLSession.shared.data(for: _request)

let postListResponse = PostListResponse() // TODO: Figure out how to get the data from an HTTP response into this object
return parser.list(response: postListResponse)
}

public func combineStrings(_ lhs: String, _ rhs: String) -> String {
wordpress_api_wrapper.combineStrings(a: lhs, b: rhs)
}
}

public extension PostListParams {
static let `default` = PostListParams(page: 1, perPage: 10)
}
16 changes: 16 additions & 0 deletions native/swift/Tests/wordpress-api/WordPressAPITests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import XCTest

import wordpress_api

final class WordPressAPITests: XCTestCase {

func testThatCombiningStringsWorks() throws {
XCTAssertEqual(WordPressAPI().combineStrings("Hello", "World"), "Hello-World")
}

// Future Test:
// func testThatRequestSkeletonWorks() async throws {
// let response = try await WordPressAPI().listPosts(params: .init(page: 1, perPage: 99))
// XCTAssertTrue(try XCTUnwrap(response.postList).isEmpty)
// }
}
2 changes: 1 addition & 1 deletion wp_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["lib", "cdylib"]
crate-type = ["lib", "cdylib", "staticlib"]
name = "wp_api"

[dependencies]
Expand Down
6 changes: 6 additions & 0 deletions wp_api/src/posts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ pub trait PostResponseParser: Send + Sync {
pub struct PostRequestBuilder {}

impl PostRequestBuilder {

// TODO: This might not be part of the long-term API
pub fn new() -> Self {
PostRequestBuilder{}
}

pub fn list(&self, params: Option<PostListParams>) -> PostListRequest {
todo!()
}
Expand Down
2 changes: 2 additions & 0 deletions wp_api/src/wp_api.udl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ interface PostResponseParser {
//
// IMPORTANT: This design does not include error handling yet!
interface PostRequestBuilder {
constructor();

PostListRequest list(PostListParams? params);
PostCreateRequest create(PostCreateParams? params);
PostRetrieveRequest retrieve(u32 post_id, PostRetrieveParams? params);
Expand Down
3 changes: 3 additions & 0 deletions wp_api/uniffi.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[bindings.kotlin]
cdylib_name = "wp_api"

[bindings.swift]
generate_immutable_records = true
2 changes: 1 addition & 1 deletion wp_networking/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["lib", "cdylib"]
crate-type = ["lib", "cdylib", "staticlib"]
name = "wp_networking"

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion wp_parsing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["lib", "cdylib"]
crate-type = ["lib", "cdylib", "staticlib"]
name = "wp_parsing"

[dependencies]
Expand Down
2 changes: 2 additions & 0 deletions wp_parsing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ impl PostResponseParser for WPPostResponseParser {
todo!()
}
}

uniffi::include_scaffolding!("wp_parsing");