Add networking layer and wire up v9 login flow with unit tests.
Introduce APIClient/AuthAPI, complete login with multi-account selection, and polish the login card UI with shadow and keyboard dismiss. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -9,10 +9,23 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
93FF17E42FFB84950033C304 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 93FF17E22FFB84950033C304 /* SnapKit */; };
|
||||
93FF17E52FFB84950033C304 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 93FF17E32FFB84950033C304 /* Kingfisher */; };
|
||||
A1B2C3D12FFB84950033C305 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 93FF17E22FFB84950033C304 /* SnapKit */; };
|
||||
A1B2C3D22FFB84950033C305 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 93FF17E32FFB84950033C304 /* Kingfisher */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
A1B2C3D82FFB84950033C305 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 93FF17BD2FFB84950033C304 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 93FF17C42FFB84950033C304;
|
||||
remoteInfo = suixinkan;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
93FF17C52FFB84950033C304 /* suixinkan.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = suixinkan.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A1B2C3D02FFB84950033C305 /* suixinkanTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = suixinkanTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
@ -34,6 +47,11 @@
|
||||
path = suixinkan;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A1B2C3D42FFB84950033C305 /* suixinkanTests */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
path = suixinkanTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -46,6 +64,15 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1B2C3D62FFB84950033C305 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A1B2C3D12FFB84950033C305 /* SnapKit in Frameworks */,
|
||||
A1B2C3D22FFB84950033C305 /* Kingfisher in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@ -53,6 +80,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
93FF17C72FFB84950033C304 /* suixinkan */,
|
||||
A1B2C3D42FFB84950033C305 /* suixinkanTests */,
|
||||
93FF17C62FFB84950033C304 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@ -61,6 +89,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
93FF17C52FFB84950033C304 /* suixinkan.app */,
|
||||
A1B2C3D02FFB84950033C305 /* suixinkanTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -92,8 +121,41 @@
|
||||
productReference = 93FF17C52FFB84950033C304 /* suixinkan.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
A1B2C3D32FFB84950033C305 /* suixinkanTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = A1B2C3DB2FFB84950033C305 /* Build configuration list for PBXNativeTarget "suixinkanTests" */;
|
||||
buildPhases = (
|
||||
A1B2C3D52FFB84950033C305 /* Sources */,
|
||||
A1B2C3D62FFB84950033C305 /* Frameworks */,
|
||||
A1B2C3D72FFB84950033C305 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
A1B2C3D92FFB84950033C305 /* PBXTargetDependency */,
|
||||
);
|
||||
fileSystemSynchronizedGroups = (
|
||||
A1B2C3D42FFB84950033C305 /* suixinkanTests */,
|
||||
);
|
||||
name = suixinkanTests;
|
||||
packageProductDependencies = (
|
||||
93FF17E22FFB84950033C304 /* SnapKit */,
|
||||
93FF17E32FFB84950033C304 /* Kingfisher */,
|
||||
);
|
||||
productName = suixinkanTests;
|
||||
productReference = A1B2C3D02FFB84950033C305 /* suixinkanTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
A1B2C3D92FFB84950033C305 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 93FF17C42FFB84950033C304 /* suixinkan */;
|
||||
targetProxy = A1B2C3D82FFB84950033C305 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
93FF17BD2FFB84950033C304 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
@ -105,6 +167,10 @@
|
||||
93FF17C42FFB84950033C304 = {
|
||||
CreatedOnToolsVersion = 26.6;
|
||||
};
|
||||
A1B2C3D32FFB84950033C305 = {
|
||||
CreatedOnToolsVersion = 26.6;
|
||||
TestTargetID = 93FF17C42FFB84950033C304;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 93FF17C02FFB84950033C304 /* Build configuration list for PBXProject "suixinkan" */;
|
||||
@ -126,6 +192,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
93FF17C42FFB84950033C304 /* suixinkan */,
|
||||
A1B2C3D32FFB84950033C305 /* suixinkanTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -138,6 +205,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1B2C3D72FFB84950033C305 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@ -148,6 +222,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A1B2C3D52FFB84950033C305 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
@ -344,6 +425,52 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A1B2C3DC2FFB84950033C305 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 56GVN5RNVN;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yuanzhixiang.suixinkanTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
||||
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/suixinkan.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/suixinkan";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A1B2C3DA2FFB84950033C305 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = 56GVN5RNVN;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.yuanzhixiang.suixinkanTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SWIFT_APPROACHABLE_CONCURRENCY = YES;
|
||||
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
|
||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/suixinkan.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/suixinkan";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@ -365,6 +492,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
A1B2C3DB2FFB84950033C305 /* Build configuration list for PBXNativeTarget "suixinkanTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A1B2C3DC2FFB84950033C305 /* Debug */,
|
||||
A1B2C3DA2FFB84950033C305 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
|
||||
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "2660"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "93FF17C42FFB84950033C304"
|
||||
BuildableName = "suixinkan.app"
|
||||
BlueprintName = "suixinkan"
|
||||
ReferencedContainer = "container:suixinkan.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO"
|
||||
parallelizable = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "A1B2C3D32FFB84950033C305"
|
||||
BuildableName = "suixinkanTests.xctest"
|
||||
BlueprintName = "suixinkanTests"
|
||||
ReferencedContainer = "container:suixinkan.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "93FF17C42FFB84950033C304"
|
||||
BuildableName = "suixinkan.app"
|
||||
BlueprintName = "suixinkan"
|
||||
ReferencedContainer = "container:suixinkan.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "93FF17C42FFB84950033C304"
|
||||
BuildableName = "suixinkan.app"
|
||||
BlueprintName = "suixinkan"
|
||||
ReferencedContainer = "container:suixinkan.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
Reference in New Issue
Block a user