fix(ios): crash at swift runtime error (#13635)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Fetch copilot model options per prompt (default, optional, pro) with
generated GraphQL query and schema types.

* **Chores**
* Upgraded iOS deps: Apollo iOS 1.23.0, EventSource 0.1.5, Swift
Collections 1.2.1.
* Switched Intelligents to static linking and updated project
integration.
* Parameterized and standardized GraphQL codegen tooling; setup
automation now syncs versions and safely backs up/restores custom
scalars.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Lakr
2025-09-23 13:56:08 +08:00
committed by GitHub
parent b25759c264
commit 75a6c79b2c
10 changed files with 184 additions and 20 deletions

View File

@@ -8,15 +8,14 @@
/* Begin PBXBuildFile section */
2E0DD47B57B994A104B25EED /* Pods_AFFiNE.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF48636D7DB5BEE00770FD9A /* Pods_AFFiNE.framework */; };
500D72F72E825064006E553F /* Intelligents in Frameworks */ = {isa = PBXBuildFile; productRef = 500D72F62E825064006E553F /* Intelligents */; };
5027D4782E7C5FBD00ADD25A /* AffinePaywall in Frameworks */ = {isa = PBXBuildFile; productRef = 5027D4772E7C5FBD00ADD25A /* AffinePaywall */; };
5027D47A2E7C5FC100ADD25A /* AffineResources in Frameworks */ = {isa = PBXBuildFile; productRef = 5027D4792E7C5FC100ADD25A /* AffineResources */; };
5027D47C2E7C5FC400ADD25A /* AffineGraphQL in Frameworks */ = {isa = PBXBuildFile; productRef = 5027D47B2E7C5FC400ADD25A /* AffineGraphQL */; };
5027D4802E7C611900ADD25A /* Tools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5027D47F2E7C611900ADD25A /* Tools.swift */; };
5075136A2D1924C600AD60C0 /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507513692D1924C600AD60C0 /* RootViewController.swift */; };
50802D612D112F8700694021 /* Intelligents in Frameworks */ = {isa = PBXBuildFile; productRef = 50802D602D112F8700694021 /* Intelligents */; settings = {ATTRIBUTES = (Required, ); }; };
50A285D72D112A5E000D5A6D /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 50A285D62D112A5E000D5A6D /* Localizable.xcstrings */; };
50A285D82D112A5E000D5A6D /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 50A285D52D112A5E000D5A6D /* InfoPlist.xcstrings */; };
50E218302E0BE1A700EA4C6E /* Intelligents in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 50802D602D112F8700694021 /* Intelligents */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
50FF428A2D2E757E0050AA83 /* ApplicationBridgedWindowScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FF42892D2E757E0050AA83 /* ApplicationBridgedWindowScript.swift */; };
50FF428C2D2E77CC0050AA83 /* AffineViewController+AIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FF428B2D2E77CC0050AA83 /* AffineViewController+AIButton.swift */; };
9D52FC432D26CDBF00105D0A /* JSValueContainerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D52FC422D26CDB600105D0A /* JSValueContainerExt.swift */; };
@@ -42,7 +41,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
50E218302E0BE1A700EA4C6E /* Intelligents in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -101,7 +99,7 @@
5027D4782E7C5FBD00ADD25A /* AffinePaywall in Frameworks */,
9DFCD1462D27D1D70028C92B /* libaffine_mobile_native.a in Frameworks */,
5027D47C2E7C5FC400ADD25A /* AffineGraphQL in Frameworks */,
50802D612D112F8700694021 /* Intelligents in Frameworks */,
500D72F72E825064006E553F /* Intelligents in Frameworks */,
2E0DD47B57B994A104B25EED /* Pods_AFFiNE.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -581,6 +579,10 @@
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
500D72F62E825064006E553F /* Intelligents */ = {
isa = XCSwiftPackageProductDependency;
productName = Intelligents;
};
5027D4772E7C5FBD00ADD25A /* AffinePaywall */ = {
isa = XCSwiftPackageProductDependency;
productName = AffinePaywall;
@@ -593,10 +595,6 @@
isa = XCSwiftPackageProductDependency;
productName = AffineGraphQL;
};
50802D602D112F8700694021 /* Intelligents */ = {
isa = XCSwiftPackageProductDependency;
productName = Intelligents;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 504EC2FC1FED79650016851F /* Project object */;

View File

@@ -5,8 +5,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apollographql/apollo-ios",
"state" : {
"revision" : "39fea7617346c0731be25f61afd537e7032fb562",
"version" : "1.22.0"
"revision" : "d591c1dd55824867877cff4f6551fe32983d7f51",
"version" : "1.23.0"
}
},
{
@@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/Recouse/EventSource",
"state" : {
"revision" : "d783b1cf60599dbcec6396c55a6bab33a1c92dc3",
"version" : "0.1.4"
"revision" : "7b2f4f585d3927876bd76eaede9fdff779eff102",
"version" : "0.1.5"
}
},
{
@@ -86,8 +86,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections",
"state" : {
"revision" : "c1805596154bb3a265fd91b8ac0c4433b4348fb0",
"version" : "1.2.0"
"revision" : "8c0c0a8b49e080e54e5e328cc552821ff07cd341",
"version" : "1.2.1"
}
},
{

View File

@@ -0,0 +1,122 @@
// @generated
// This file was automatically generated and should not be edited.
@_exported import ApolloAPI
public class GetPromptModelsQuery: GraphQLQuery {
public static let operationName: String = "getPromptModels"
public static let operationDocument: ApolloAPI.OperationDocument = .init(
definition: .init(
#"query getPromptModels($promptName: String!) { currentUser { __typename copilot { __typename models(promptName: $promptName) { __typename defaultModel optionalModels { __typename id name } proModels { __typename id name } } } } }"#
))
public var promptName: String
public init(promptName: String) {
self.promptName = promptName
}
public var __variables: Variables? { ["promptName": promptName] }
public struct Data: AffineGraphQL.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
public static var __selections: [ApolloAPI.Selection] { [
.field("currentUser", CurrentUser?.self),
] }
/// Get current user
public var currentUser: CurrentUser? { __data["currentUser"] }
/// CurrentUser
///
/// Parent Type: `UserType`
public struct CurrentUser: AffineGraphQL.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("copilot", Copilot.self),
] }
public var copilot: Copilot { __data["copilot"] }
/// CurrentUser.Copilot
///
/// Parent Type: `Copilot`
public struct Copilot: AffineGraphQL.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("models", Models.self, arguments: ["promptName": .variable("promptName")]),
] }
/// List available models for a prompt, with human-readable names
public var models: Models { __data["models"] }
/// CurrentUser.Copilot.Models
///
/// Parent Type: `CopilotModelsType`
public struct Models: AffineGraphQL.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotModelsType }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("defaultModel", String.self),
.field("optionalModels", [OptionalModel].self),
.field("proModels", [ProModel].self),
] }
public var defaultModel: String { __data["defaultModel"] }
public var optionalModels: [OptionalModel] { __data["optionalModels"] }
public var proModels: [ProModel] { __data["proModels"] }
/// CurrentUser.Copilot.Models.OptionalModel
///
/// Parent Type: `CopilotModelType`
public struct OptionalModel: AffineGraphQL.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotModelType }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("id", String.self),
.field("name", String.self),
] }
public var id: String { __data["id"] }
public var name: String { __data["name"] }
}
/// CurrentUser.Copilot.Models.ProModel
///
/// Parent Type: `CopilotModelType`
public struct ProModel: AffineGraphQL.SelectionSet {
public let __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotModelType }
public static var __selections: [ApolloAPI.Selection] { [
.field("__typename", String.self),
.field("id", String.self),
.field("name", String.self),
] }
public var id: String { __data["id"] }
public var name: String { __data["name"] }
}
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
// @generated
// This file was automatically generated and should not be edited.
import ApolloAPI
public extension Objects {
static let CopilotModelType = ApolloAPI.Object(
typename: "CopilotModelType",
implementedInterfaces: [],
keyFields: nil
)
}

View File

@@ -0,0 +1,12 @@
// @generated
// This file was automatically generated and should not be edited.
import ApolloAPI
public extension Objects {
static let CopilotModelsType = ApolloAPI.Object(
typename: "CopilotModelsType",
implementedInterfaces: [],
keyFields: nil
)
}

View File

@@ -41,6 +41,8 @@ public enum SchemaMetadata: ApolloAPI.SchemaMetadata {
case "CopilotContextFile": return AffineGraphQL.Objects.CopilotContextFile
case "CopilotHistories": return AffineGraphQL.Objects.CopilotHistories
case "CopilotHistoriesTypeEdge": return AffineGraphQL.Objects.CopilotHistoriesTypeEdge
case "CopilotModelType": return AffineGraphQL.Objects.CopilotModelType
case "CopilotModelsType": return AffineGraphQL.Objects.CopilotModelsType
case "CopilotPromptConfigType": return AffineGraphQL.Objects.CopilotPromptConfigType
case "CopilotPromptMessageType": return AffineGraphQL.Objects.CopilotPromptMessageType
case "CopilotPromptType": return AffineGraphQL.Objects.CopilotPromptType

View File

@@ -10,7 +10,8 @@ let package = Package(
.iOS(.v16),
],
products: [
.library(name: "Intelligents", type: .dynamic, targets: ["Intelligents"]),
// static linking is required or GraphQL (ApolloAPI) will crash
.library(name: "Intelligents", type: .static, targets: ["Intelligents"]),
],
dependencies: [
.package(path: "../AffineGraphQL"),

View File

@@ -4,8 +4,7 @@ cd "$(dirname "$0")"
set -euo pipefail
VERSION=$(grep -o 'apollo-ios", exact: "[^"]*"' "App/Packages/AffineGraphQL/Package.swift" | sed 's/.*exact: "\([^"]*\)".*/\1/')
[ -z "$VERSION" ] && { echo "❌ Failed to extract version"; exit 1; }
VERSION=${1:-"1.23.0"} # Use first argument or default to 1.23.0
echo "📦 Apollo Version: $VERSION"
sed -i '' "s|apollo-ios\.git\", from: \"[^\"]*\"|apollo-ios.git\", from: \"$VERSION\"|" "App/Packages/Intelligents/Package.swift"

View File

@@ -9,8 +9,12 @@ const PackageRoot = iosPackage.path;
console.log('[*] PackageRoot', PackageRoot);
const version = process.argv[2] || '1.23.0'; // Default to 1.23.0 if no version provided
console.log('[*] graphql...');
execSync(`${PackageRoot}/apollo-codegen-chore.sh`, { stdio: 'inherit' });
execSync(`${PackageRoot}/apollo-codegen-chore.sh "${version}"`, {
stdio: 'inherit',
});
console.log('[*] rust...');
execSync(

View File

@@ -38,9 +38,23 @@ rustup target add aarch64-apple-ios
rustup target add aarch64-apple-ios-sim
rustup target add aarch64-apple-darwin
echo "[*] syncing apollo version..."
LATEST_VERSION="1.23.0"
sed -i '' "s/exact: \"[^\"]*\"/exact: \"$LATEST_VERSION\"/g" $SCRIPT_DIR_PATH/App/Packages/AffineGraphQL/Package.swift
echo "[*] apollo version synced to $LATEST_VERSION"
echo "[*] backing up CustomScalars..."
TEMP_DIR=$(mktemp -d)
mkdir -p "$TEMP_DIR"
function cleanup { rm -rf "$TEMP_DIR"; }
trap cleanup EXIT
CUSTOM_SCALARS_DIR=$SCRIPT_DIR_PATH/App/Packages/AffineGraphQL/Sources/Schema/CustomScalars
cp -r $CUSTOM_SCALARS_DIR/* $TEMP_DIR/
echo "[*] codegen..."
yarn affine @affine/ios codegen
rm -rf $CUSTOM_SCALARS_DIR/*
yarn affine @affine/ios codegen "1.23.0"
cp -r $TEMP_DIR/* $CUSTOM_SCALARS_DIR/
echo "[+] setup complete"
yarn affine @affine/ios xcode