Commit 4a7abd98 authored by Wei Han's avatar Wei Han

code update

parent 87014f12
......@@ -7,8 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
09422FEEE292BF7FDB944B44 /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7646DEA673059A6FBED034D5 /* libPods-example.a */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
305DBAC1A0BEA3CAED44A62D /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20C2E11D8F9CB707F74FE9BB /* libPods-example.a */; };
44006126336D83DB220E7214 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; };
761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
......@@ -19,12 +19,12 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = "<group>"; };
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = example/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
5350E2781CCDA8D204AD92D7 /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = "<group>"; };
66DA0C9F0E73892891015312 /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = "<group>"; };
20C2E11D8F9CB707F74FE9BB /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = example/AppDelegate.swift; sourceTree = "<group>"; };
7646DEA673059A6FBED034D5 /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = example/LaunchScreen.storyboard; sourceTree = "<group>"; };
A73ECAAA402D2F3FA2A038B4 /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
F58A99A1418BFFCA17EA3A73 /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -32,7 +32,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
09422FEEE292BF7FDB944B44 /* libPods-example.a in Frameworks */,
305DBAC1A0BEA3CAED44A62D /* libPods-example.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -55,7 +55,7 @@
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
7646DEA673059A6FBED034D5 /* libPods-example.a */,
20C2E11D8F9CB707F74FE9BB /* libPods-example.a */,
);
name = Frameworks;
sourceTree = "<group>";
......@@ -92,8 +92,8 @@
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup;
children = (
5350E2781CCDA8D204AD92D7 /* Pods-example.debug.xcconfig */,
66DA0C9F0E73892891015312 /* Pods-example.release.xcconfig */,
F58A99A1418BFFCA17EA3A73 /* Pods-example.debug.xcconfig */,
A73ECAAA402D2F3FA2A038B4 /* Pods-example.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
......@@ -105,13 +105,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */;
buildPhases = (
1A63BC39C4970FBC7B74189D /* [CP] Check Pods Manifest.lock */,
448EFC1B200E72FABB8D5D7E /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
4C643B981BE7FEF41566F449 /* [CP] Embed Pods Frameworks */,
4DB8EF54BF2FC8DAD832C9D8 /* [CP] Copy Pods Resources */,
18D01E9BF38825650F353B4D /* [CP] Embed Pods Frameworks */,
CCF6FD120FD8E8FD6C5FCB1F /* [CP] Copy Pods Resources */,
);
buildRules = (
);
......@@ -183,46 +183,46 @@
shellPath = /bin/sh;
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
};
1A63BC39C4970FBC7B74189D /* [CP] Check Pods Manifest.lock */ = {
18D01E9BF38825650F353B4D /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt",
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
4C643B981BE7FEF41566F449 /* [CP] Embed Pods Frameworks */ = {
448EFC1B200E72FABB8D5D7E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-frameworks.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
4DB8EF54BF2FC8DAD832C9D8 /* [CP] Copy Pods Resources */ = {
CCF6FD120FD8E8FD6C5FCB1F /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
......@@ -255,7 +255,7 @@
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5350E2781CCDA8D204AD92D7 /* Pods-example.debug.xcconfig */;
baseConfigurationReference = F58A99A1418BFFCA17EA3A73 /* Pods-example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
......@@ -283,7 +283,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 66DA0C9F0E73892891015312 /* Pods-example.release.xcconfig */;
baseConfigurationReference = A73ECAAA402D2F3FA2A038B4 /* Pods-example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
......
......@@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
......
......@@ -14,10 +14,37 @@
2FB975E02ED7F9AA00E64A87 /* EventKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FB975DF2ED7F9AA00E64A87 /* EventKit.framework */; };
2FBC22B52EF93B8A00882B6F /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FBC22B42EF93B8A00882B6F /* UniformTypeIdentifiers.framework */; };
2FBC22B72EF93BB400882B6F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FBC22B62EF93BB400882B6F /* UIKit.framework */; };
2FC779B42F0E1C5B0002A1D4 /* QmsPluginFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F9647652E86307D002CC7CB /* QmsPluginFramework.framework */; };
2FC779B52F0E1C5B0002A1D4 /* QmsPluginFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 2F9647652E86307D002CC7CB /* QmsPluginFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2FC779BD2F0E33410002A1D4 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FC779BC2F0E33410002A1D4 /* MobileCoreServices.framework */; };
2FD1557B2ECAC5CC00233981 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FD1557A2ECAC5CC00233981 /* WebKit.framework */; };
2FD9A1AE2EF0FA7100A7B53E /* Network.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FD9A0B72EF0E85B00A7B53E /* Network.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
2FC779B62F0E1C5B0002A1D4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2F96475C2E86307D002CC7CB /* Project object */;
proxyType = 1;
remoteGlobalIDString = 2F9647642E86307D002CC7CB;
remoteInfo = QmsPluginFramework;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
2FC779B82F0E1C5C0002A1D4 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
2FC779B52F0E1C5B0002A1D4 /* QmsPluginFramework.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
2F8D09082E9605E200C764FF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; };
2F9647652E86307D002CC7CB /* QmsPluginFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = QmsPluginFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
......@@ -28,12 +55,21 @@
2FB975DF2ED7F9AA00E64A87 /* EventKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.1.sdk/System/Library/Frameworks/EventKit.framework; sourceTree = DEVELOPER_DIR; };
2FBC22B42EF93B8A00882B6F /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; };
2FBC22B62EF93BB400882B6F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
2FC779A92F0E1C310002A1D4 /* testApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
2FC779BC2F0E33410002A1D4 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
2FD027B02EEFD25100CF5C33 /* Network.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Network.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.1.sdk/System/Library/Frameworks/Network.framework; sourceTree = DEVELOPER_DIR; };
2FD1557A2ECAC5CC00233981 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.1.sdk/System/iOSSupport/System/Library/PrivateFrameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; };
2FD9A0B72EF0E85B00A7B53E /* Network.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Network.framework; path = System/Library/Frameworks/Network.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
2FC779BF2F0E37B30002A1D4 /* Exceptions for "testApp" folder in "testApp" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = 2FC779A82F0E1C310002A1D4 /* testApp */;
};
2FD9A0B92EF0F7FD00A7B53E /* Exceptions for "QmsPluginFramework" folder in "QmsPluginFramework" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
......@@ -56,6 +92,14 @@
path = QmsPluginFramework;
sourceTree = "<group>";
};
2FC779AA2F0E1C310002A1D4 /* testApp */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
2FC779BF2F0E37B30002A1D4 /* Exceptions for "testApp" folder in "testApp" target */,
);
path = testApp;
sourceTree = "<group>";
};
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
......@@ -66,6 +110,7 @@
2FBC22B72EF93BB400882B6F /* UIKit.framework in Frameworks */,
2FBC22B52EF93B8A00882B6F /* UniformTypeIdentifiers.framework in Frameworks */,
2FD9A1AE2EF0FA7100A7B53E /* Network.framework in Frameworks */,
2FC779BD2F0E33410002A1D4 /* MobileCoreServices.framework in Frameworks */,
2FB975E02ED7F9AA00E64A87 /* EventKit.framework in Frameworks */,
2FD1557B2ECAC5CC00233981 /* WebKit.framework in Frameworks */,
2FB2922A2EAB04F400D9F164 /* AVFoundation.framework in Frameworks */,
......@@ -75,6 +120,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2FC779A62F0E1C310002A1D4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2FC779B42F0E1C5B0002A1D4 /* QmsPluginFramework.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
......@@ -82,6 +135,7 @@
isa = PBXGroup;
children = (
2F9647672E86307D002CC7CB /* QmsPluginFramework */,
2FC779AA2F0E1C310002A1D4 /* testApp */,
2FAEF0982E8B7BC80086EDA3 /* Frameworks */,
2F9647662E86307D002CC7CB /* Products */,
);
......@@ -91,6 +145,7 @@
isa = PBXGroup;
children = (
2F9647652E86307D002CC7CB /* QmsPluginFramework.framework */,
2FC779A92F0E1C310002A1D4 /* testApp.app */,
);
name = Products;
sourceTree = "<group>";
......@@ -98,6 +153,7 @@
2FAEF0982E8B7BC80086EDA3 /* Frameworks */ = {
isa = PBXGroup;
children = (
2FC779BC2F0E33410002A1D4 /* MobileCoreServices.framework */,
2FBC22B62EF93BB400882B6F /* UIKit.framework */,
2FBC22B42EF93B8A00882B6F /* UniformTypeIdentifiers.framework */,
2FD027B02EEFD25100CF5C33 /* Network.framework */,
......@@ -147,6 +203,30 @@
productReference = 2F9647652E86307D002CC7CB /* QmsPluginFramework.framework */;
productType = "com.apple.product-type.framework";
};
2FC779A82F0E1C310002A1D4 /* testApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2FC779B32F0E1C370002A1D4 /* Build configuration list for PBXNativeTarget "testApp" */;
buildPhases = (
2FC779A52F0E1C310002A1D4 /* Sources */,
2FC779A62F0E1C310002A1D4 /* Frameworks */,
2FC779A72F0E1C310002A1D4 /* Resources */,
2FC779B82F0E1C5C0002A1D4 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
2FC779B72F0E1C5B0002A1D4 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
2FC779AA2F0E1C310002A1D4 /* testApp */,
);
name = testApp;
packageProductDependencies = (
);
productName = testApp;
productReference = 2FC779A92F0E1C310002A1D4 /* testApp.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
......@@ -154,11 +234,15 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 2620;
LastUpgradeCheck = 2600;
TargetAttributes = {
2F9647642E86307D002CC7CB = {
CreatedOnToolsVersion = 26.0.1;
};
2FC779A82F0E1C310002A1D4 = {
CreatedOnToolsVersion = 26.2;
};
};
};
buildConfigurationList = 2F96475F2E86307D002CC7CB /* Build configuration list for PBXProject "QmsPluginFramework" */;
......@@ -176,6 +260,7 @@
projectRoot = "";
targets = (
2F9647642E86307D002CC7CB /* QmsPluginFramework */,
2FC779A82F0E1C310002A1D4 /* testApp */,
);
};
/* End PBXProject section */
......@@ -188,6 +273,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2FC779A72F0E1C310002A1D4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
......@@ -198,8 +290,23 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2FC779A52F0E1C310002A1D4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
2FC779B72F0E1C5B0002A1D4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 2F9647642E86307D002CC7CB /* QmsPluginFramework */;
targetProxy = 2FC779B62F0E1C5B0002A1D4 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
2F96476E2E86307D002CC7CB /* Debug */ = {
isa = XCBuildConfiguration;
......@@ -405,6 +512,77 @@
};
name = Release;
};
2FC779B12F0E1C370002A1D4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 54TZWRHSND;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = testApp/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 26.2;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = test.testApp;
PRODUCT_NAME = "$(TARGET_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
2FC779B22F0E1C370002A1D4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 54TZWRHSND;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = testApp/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 26.2;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = test.testApp;
PRODUCT_NAME = "$(TARGET_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
......@@ -426,6 +604,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2FC779B32F0E1C370002A1D4 /* Build configuration list for PBXNativeTarget "testApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2FC779B12F0E1C370002A1D4 /* Debug */,
2FC779B22F0E1C370002A1D4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 2F96475C2E86307D002CC7CB /* Project object */;
......
......@@ -376,8 +376,7 @@
#pragma mark - Api
- (void)requestAccessItem{
[APIClient requestAccessItem:@"135"
completion:^(BOOL success, NSDictionary *data, NSError *error) {
[APIClient requestAccessItem:^(BOOL success, NSDictionary *data, NSError *error) {
NSLog(@"📦 Received General Info Data: %@", data);
NSDictionary *general = data[@"Data"];
......
......@@ -15,6 +15,11 @@ NS_ASSUME_NONNULL_BEGIN
clientCode:(NSString *)clientCode
userToken:(NSString *)userToken;
@property (nonatomic, copy) NSString *projectCode;
@property (nonatomic, copy) NSString *projectName;
@property (nonatomic, copy) NSString *projectId;
@property (nonatomic, copy) NSString *drawingPlanId;
@end
NS_ASSUME_NONNULL_END
......@@ -13,6 +13,7 @@
#import "AccessItemViewController.h"
#import "OfflineSyncManager.h"
#import "LocalStorage.h"
#import "APIConfig.h"
@interface DashboardViewController ()
......@@ -29,8 +30,6 @@
@property (nonatomic, assign) NSInteger intPendingAccessCount;
@property (nonatomic, assign) BOOL bln_ReminderPA;
@property (nonatomic, assign) BOOL bln_POASignOff;
@property (nonatomic, strong) NSString *projectCode;
@property (nonatomic, strong) NSString *projectName;
@property (nonatomic, strong) UIImage *headerBackgroundImage;
@property (nonatomic, strong) NSArray *announcements;
@property (nonatomic, strong) UIView *loadingOverlay;
......@@ -41,6 +40,7 @@
@property (nonatomic, strong) UILabel *projectNameLabel;
@property (nonatomic, strong) UILabel *unitNameLabel;
@property (nonatomic, strong) UIButton *infoButton;
@property (nonatomic, strong) UIButton *backButton;
@end
......@@ -68,13 +68,13 @@
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
_sectionViews = [NSMutableDictionary dictionary];
[APIConfig setProjectId:self.projectId];
[APIConfig setDrawingPlanId:self.drawingPlanId];
[self setupHeader];
[self setupScrollContent];
[self setupFooter];
self.projectCode = @"PTD197656";
self.projectName = @"Ara E`Residence Dev";
[self showLoadingOverlay:@"Loading dashboard..."];
[self checkAndRefreshAPIs];
......@@ -90,6 +90,12 @@
NSLog(@"Dashboard loaded, refreshing data");
[self refreshDashboardContent];
NSLog(@"in viewWillAppear ClientID: %@, ClientCode: %@, user_token: %@", self.ClientID, self.ClientCode, self.user_token);
self.navigationController.navigationBarHidden = YES;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.navigationController.navigationBarHidden = YES;
}
- (void)checkAndRefreshAPIs {
......@@ -302,7 +308,24 @@
self.unitNameLabel.text = @"";
});
});
}
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"]
forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self
action:@selector(onBack)
forControlEvents:UIControlEventTouchUpInside];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.backButton];
[NSLayoutConstraint activateConstraints:@[
[self.backButton.leadingAnchor constraintEqualToAnchor:headerBar.leadingAnchor constant:8],
[self.backButton.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:24],
[self.backButton.heightAnchor constraintEqualToConstant:24],
]];
}
- (void)handleBackButtonTapped {
......@@ -1292,4 +1315,8 @@
[self checkAndRefreshAPIs];
}
- (void)onBack {
[self.navigationController popViewControllerAnimated:YES];
}
@end
......@@ -33,74 +33,74 @@
CGFloat topHeight = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 180 : 120;
// HEADER CONTAINER
self.headerContainer = [[UIView alloc] init];
self.headerContainer.translatesAutoresizingMaskIntoConstraints = NO;
self.headerContainer.backgroundColor = [UIColor colorWithRed:0 green:0.42 blue:0.55 alpha:1.0];
[self.view addSubview:self.headerContainer];
[NSLayoutConstraint activateConstraints:@[
[self.headerContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerContainer.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.headerContainer.heightAnchor constraintEqualToConstant:topHeight],
]];
// TOUCHABLE HEADER
UIButton *profileTap = [UIButton buttonWithType:UIButtonTypeCustom];
profileTap.translatesAutoresizingMaskIntoConstraints = NO;
[profileTap addTarget:self action:@selector(profileTapped) forControlEvents:UIControlEventTouchUpInside];
[self.headerContainer addSubview:profileTap];
[NSLayoutConstraint activateConstraints:@[
[profileTap.leadingAnchor constraintEqualToAnchor:self.headerContainer.leadingAnchor],
[profileTap.trailingAnchor constraintEqualToAnchor:self.headerContainer.trailingAnchor],
[profileTap.topAnchor constraintEqualToAnchor:self.headerContainer.topAnchor],
[profileTap.bottomAnchor constraintEqualToAnchor:self.headerContainer.bottomAnchor],
]];
// AVATAR
CGFloat avatarSize = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 100 : 50;
self.avatarView = [[UIImageView alloc] init];
self.avatarView.translatesAutoresizingMaskIntoConstraints = NO;
self.avatarView.layer.cornerRadius = avatarSize / 2.0;
self.avatarView.clipsToBounds = YES;
self.avatarView.layer.borderColor = [UIColor whiteColor].CGColor;
self.avatarView.layer.borderWidth = 1.0;
self.avatarView.contentMode = UIViewContentModeScaleAspectFill;
[self.headerContainer addSubview:self.avatarView];
[NSLayoutConstraint activateConstraints:@[
[self.avatarView.leadingAnchor constraintEqualToAnchor:self.headerContainer.leadingAnchor constant:18],
[self.avatarView.centerYAnchor constraintEqualToAnchor:self.headerContainer.centerYAnchor],
[self.avatarView.widthAnchor constraintEqualToConstant:avatarSize],
[self.avatarView.heightAnchor constraintEqualToConstant:avatarSize],
]];
// // HEADER CONTAINER
// self.headerContainer = [[UIView alloc] init];
// self.headerContainer.translatesAutoresizingMaskIntoConstraints = NO;
// self.headerContainer.backgroundColor = [UIColor colorWithRed:0 green:0.42 blue:0.55 alpha:1.0];
// [self.view addSubview:self.headerContainer];
//
// [NSLayoutConstraint activateConstraints:@[
// [self.headerContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
// [self.headerContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
// [self.headerContainer.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
// [self.headerContainer.heightAnchor constraintEqualToConstant:topHeight],
// ]];
//
// // TOUCHABLE HEADER
// UIButton *profileTap = [UIButton buttonWithType:UIButtonTypeCustom];
// profileTap.translatesAutoresizingMaskIntoConstraints = NO;
// [profileTap addTarget:self action:@selector(profileTapped) forControlEvents:UIControlEventTouchUpInside];
// [self.headerContainer addSubview:profileTap];
//
// [NSLayoutConstraint activateConstraints:@[
// [profileTap.leadingAnchor constraintEqualToAnchor:self.headerContainer.leadingAnchor],
// [profileTap.trailingAnchor constraintEqualToAnchor:self.headerContainer.trailingAnchor],
// [profileTap.topAnchor constraintEqualToAnchor:self.headerContainer.topAnchor],
// [profileTap.bottomAnchor constraintEqualToAnchor:self.headerContainer.bottomAnchor],
// ]];
//
// // AVATAR
// CGFloat avatarSize = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 100 : 50;
// self.avatarView = [[UIImageView alloc] init];
// self.avatarView.translatesAutoresizingMaskIntoConstraints = NO;
// self.avatarView.layer.cornerRadius = avatarSize / 2.0;
// self.avatarView.clipsToBounds = YES;
// self.avatarView.layer.borderColor = [UIColor whiteColor].CGColor;
// self.avatarView.layer.borderWidth = 1.0;
// self.avatarView.contentMode = UIViewContentModeScaleAspectFill;
// [self.headerContainer addSubview:self.avatarView];
//
// [NSLayoutConstraint activateConstraints:@[
// [self.avatarView.leadingAnchor constraintEqualToAnchor:self.headerContainer.leadingAnchor constant:18],
// [self.avatarView.centerYAnchor constraintEqualToAnchor:self.headerContainer.centerYAnchor],
// [self.avatarView.widthAnchor constraintEqualToConstant:avatarSize],
// [self.avatarView.heightAnchor constraintEqualToConstant:avatarSize],
// ]];
// NAME LABEL
self.nameLabel = [[UILabel alloc] init];
self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.nameLabel.textColor = UIColor.whiteColor;
self.nameLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightRegular];
self.nameLabel.numberOfLines = 2;
[self.headerContainer addSubview:self.nameLabel];
// EMAIL LABEL
self.emailLabel = [[UILabel alloc] init];
self.emailLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.emailLabel.textColor = UIColor.whiteColor;
self.emailLabel.font = [UIFont systemFontOfSize:14];
[self.headerContainer addSubview:self.emailLabel];
[NSLayoutConstraint activateConstraints:@[
[self.nameLabel.leadingAnchor constraintEqualToAnchor:self.avatarView.trailingAnchor constant:16],
[self.nameLabel.trailingAnchor constraintEqualToAnchor:self.headerContainer.trailingAnchor constant:-18],
[self.nameLabel.bottomAnchor constraintEqualToAnchor:self.headerContainer.centerYAnchor constant:-4],
[self.emailLabel.leadingAnchor constraintEqualToAnchor:self.nameLabel.leadingAnchor],
[self.emailLabel.trailingAnchor constraintEqualToAnchor:self.nameLabel.trailingAnchor],
[self.emailLabel.topAnchor constraintEqualToAnchor:self.nameLabel.bottomAnchor constant:4],
]];
// self.nameLabel = [[UILabel alloc] init];
// self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
// self.nameLabel.textColor = UIColor.whiteColor;
// self.nameLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightRegular];
// self.nameLabel.numberOfLines = 2;
// [self.headerContainer addSubview:self.nameLabel];
//
// // EMAIL LABEL
// self.emailLabel = [[UILabel alloc] init];
// self.emailLabel.translatesAutoresizingMaskIntoConstraints = NO;
// self.emailLabel.textColor = UIColor.whiteColor;
// self.emailLabel.font = [UIFont systemFontOfSize:14];
// [self.headerContainer addSubview:self.emailLabel];
//
// [NSLayoutConstraint activateConstraints:@[
// [self.nameLabel.leadingAnchor constraintEqualToAnchor:self.avatarView.trailingAnchor constant:16],
// [self.nameLabel.trailingAnchor constraintEqualToAnchor:self.headerContainer.trailingAnchor constant:-18],
// [self.nameLabel.bottomAnchor constraintEqualToAnchor:self.headerContainer.centerYAnchor constant:-4],
//
// [self.emailLabel.leadingAnchor constraintEqualToAnchor:self.nameLabel.leadingAnchor],
// [self.emailLabel.trailingAnchor constraintEqualToAnchor:self.nameLabel.trailingAnchor],
// [self.emailLabel.topAnchor constraintEqualToAnchor:self.nameLabel.bottomAnchor constant:4],
// ]];
// MENU TABLE
self.table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
......@@ -112,7 +112,8 @@
[self.view addSubview:self.table];
[NSLayoutConstraint activateConstraints:@[
[self.table.topAnchor constraintEqualToAnchor:self.headerContainer.bottomAnchor],
// [self.table.topAnchor constraintEqualToAnchor:self.headerContainer.bottomAnchor],
[self.table.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:topHeight],
[self.table.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.table.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.table.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
......@@ -120,33 +121,33 @@
}
- (void)loadDefaultsIfNeeded {
if (!self.profileName) self.profileName = @"Guest User";
if (!self.profileEmail) self.profileEmail = @"guest@example.com";
if (!self.profileImageURL) self.profileImageURL = nil;
self.nameLabel.text = self.profileName;
self.emailLabel.text = self.profileEmail;
if (self.profileImageURL) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *d = [NSData dataWithContentsOfURL:self.profileImageURL];
UIImage *img = d ? [UIImage imageWithData:d] : [UIImage imageNamed:@"small_placeholder"];
dispatch_async(dispatch_get_main_queue(), ^{
self.avatarView.image = img;
});
});
} else {
self.avatarView.image = [UIImage imageNamed:@"small_placeholder"];
}
// if (!self.profileName) self.profileName = @"Guest User";
// if (!self.profileEmail) self.profileEmail = @"guest@example.com";
// if (!self.profileImageURL) self.profileImageURL = nil;
//
// self.nameLabel.text = self.profileName;
// self.emailLabel.text = self.profileEmail;
//
// if (self.profileImageURL) {
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// NSData *d = [NSData dataWithContentsOfURL:self.profileImageURL];
// UIImage *img = d ? [UIImage imageWithData:d] : [UIImage imageNamed:@"small_placeholder"];
// dispatch_async(dispatch_get_main_queue(), ^{
// self.avatarView.image = img;
// });
// });
// } else {
// self.avatarView.image = [UIImage imageNamed:@"small_placeholder"];
// }
if (!self.menuItems) {
self.menuItems = @[
@{@"title": @"Project List", @"action": @"projectList"},
@{@"title": @"Notification", @"action": @"notification"},
@{@"title": @"Announcement", @"action": @"announcement"},
@{@"title": @"Help", @"action": @"help"},
// @{@"title": @"Project List", @"action": @"projectList"},
// @{@"title": @"Notification", @"action": @"notification"},
// @{@"title": @"Announcement", @"action": @"announcement"},
// @{@"title": @"Help", @"action": @"help"},
@{@"title": @"Sync", @"action": @"sync"},
@{@"title": @"Logout", @"action": @"logout"}
// @{@"title": @"Logout", @"action": @"logout"}
];
}
[self.table reloadData];
......@@ -155,7 +156,7 @@
#pragma mark - Profile tap
- (void)profileTapped {
// Post a notification to navigate
[[NSNotificationCenter defaultCenter] postNotificationName:DrawerDidSelectItemNotification object:nil userInfo:@{@"action": @"profile"}];
// [[NSNotificationCenter defaultCenter] postNotificationName:DrawerDidSelectItemNotification object:nil userInfo:@{@"action": @"profile"}];
}
#pragma mark - Table datasource/delegate
......@@ -224,6 +225,4 @@
}
}
@end
// ProjectViewController.mm
#import "ProjectViewController.h"
#import "APIClient.h"
#import "APIConfig.h"
#import "UnitViewController.h"
@interface ProjectCardCell : UICollectionViewCell
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UILabel *nameLabel;
@end
@implementation ProjectCardCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.contentView.backgroundColor = UIColor.secondarySystemBackgroundColor;
self.layer.cornerRadius = 8;
self.layer.shadowColor = UIColor.blackColor.CGColor;
self.layer.shadowOpacity = 0.15;
self.layer.shadowOffset = CGSizeMake(0, 4);
self.layer.shadowRadius = 6;
self.layer.masksToBounds = NO;
self.contentView.layer.cornerRadius = 8;
self.contentView.clipsToBounds = YES;
// image
self.imageView = [[UIImageView alloc] init];
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.imageView];
// label
self.nameLabel = [[UILabel alloc] init];
self.nameLabel.font = [UIFont boldSystemFontOfSize:20];
self.nameLabel.textColor = UIColor.whiteColor;
self.nameLabel.backgroundColor =
[[UIColor blackColor] colorWithAlphaComponent:0.35];
self.nameLabel.numberOfLines = 2;
self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.nameLabel];
// constraints
[NSLayoutConstraint activateConstraints:@[
[self.imageView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor],
[self.imageView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[self.imageView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
[self.imageView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor],
[self.nameLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:8],
[self.nameLabel.trailingAnchor constraintLessThanOrEqualToAnchor:self.contentView.trailingAnchor constant:-8],
[self.nameLabel.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-8],
]];
}
return self;
}
@end
@interface ProjectViewController () <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@interface ProjectViewController ()
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UICollectionView *projectCollectionView;
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSArray *projects;
@end
@implementation ProjectViewController
......@@ -12,8 +76,20 @@
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.systemBackgroundColor;
[self requestProjectList];
[self requestCompanyCode];
[self setupHeader];
[self setupCollectionView];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.navigationController.navigationBarHidden = YES;
}
#pragma mark - Header Setup
......@@ -40,12 +116,198 @@
[menuButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[menuButton.widthAnchor constraintEqualToConstant:26],
[menuButton.heightAnchor constraintEqualToConstant:26],
]];
}
#pragma mark - Setup Collection View
- (void)setupCollectionView {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.minimumLineSpacing = 16;
layout.minimumInteritemSpacing = 16;
layout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;
self.collectionView.backgroundColor = UIColor.systemBackgroundColor;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
// register cell class
[self.collectionView registerClass:[ProjectCardCell class] forCellWithReuseIdentifier:@"ProjectCardCell"];
[self.view addSubview:self.collectionView];
// constraints
[NSLayoutConstraint activateConstraints:@[
[self.collectionView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:8],
[self.collectionView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.collectionView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
]];
}
#pragma mark - UICollectionView DataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.projects.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ProjectCardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ProjectCardCell"
forIndexPath:indexPath];
cell.imageView.image = [UIImage systemImageNamed:@"photo"];
NSDictionary *project = self.projects[indexPath.item];
// Project name
cell.nameLabel.text = project[@"project_name"];
// Project logo
NSString *logoURLString = project[@"logo"] ?: project[@"logo_thumbnail"];
NSURL *url = [NSURL URLWithString:logoURLString];
// Async load image (simple placeholder approach)
NSIndexPath *currentIndexPath = indexPath;
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = data ? [UIImage imageWithData:data] : nil;
dispatch_async(dispatch_get_main_queue(), ^{
NSIndexPath *visibleIndexPath = [collectionView indexPathForCell:cell];
if (visibleIndexPath && visibleIndexPath.item == currentIndexPath.item) {
cell.imageView.image = image ?: [UIImage systemImageNamed:@"photo"];
}
});
});
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *project = self.projects[indexPath.item];
UnitViewController *vc = [[UnitViewController alloc] init];
vc.projectId = [project[@"id"] description];
vc.projectName = project[@"project_name"];
vc.units = project[@"unit"];
vc.drawerController = self.drawerController;
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self.navigationController pushViewController:vc animated:YES];
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat horizontalInset = 16 * 2; // section inset left + right
CGFloat width = collectionView.bounds.size.width - horizontalInset;
CGFloat height = 200; // OG-style banner height
return CGSizeMake(width, height);
}
#pragma mark - API
- (void)requestProjectList {
[APIClient requestProjectList:^(NSDictionary *data, NSError *error) {
// debug
NSString *plainText = [NSString stringWithFormat:@"%@", data];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docsPath stringByAppendingPathComponent:@"projectList.txt"];
[plainText writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"📁 projectList saved as plain text to: %@", filePath);
if (error || !data) {
NSLog(@"❌ Project list API failed: %@", error);
return;
}
// RN parity: status_code check
if (data[@"status_code"]) {
NSLog(@"❌ API status error: %@", data[@"message"]);
return;
}
NSDictionary *appData = data[@"AppData"];
if (![appData[@"status"] isEqualToString:@"success"]) {
NSLog(@"❌ API failure: %@", appData[@"message"]);
return;
}
NSArray *projects = data[@"Data"];
if (![projects isKindOfClass:[NSArray class]]) {
NSLog(@"❌ Invalid project list format");
return;
}
if (!error) {
self.projects = projects;
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
if (self.projects.count == 1) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
[self collectionView:self.collectionView didSelectItemAtIndexPath:indexPath];
}
});
}
}];
}
- (void)requestCompanyCode {
[APIClient requestCompanyCode:@"kita" completion:^(NSDictionary *data, NSError *error) {
// debug
NSString *plainText = [NSString stringWithFormat:@"%@", data];
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *filePath = [docsPath stringByAppendingPathComponent:@"companyCode.txt"];
[plainText writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSLog(@"📁 companyCode saved as plain text to: %@", filePath);
if (error || !data) {
NSLog(@"❌ Company Code API failed: %@", error);
return;
}
// RN parity: status_code check
if (data[@"status_code"]) {
NSLog(@"❌ Company Code error: %@", data[@"message"]);
return;
}
NSDictionary *appData = data[@"AppData"];
if (![appData[@"status"] isEqualToString:@"success"]) {
NSLog(@"❌ API failure: %@", appData[@"message"]);
return;
}
NSArray *project = data[@"Data"];
if (![project isKindOfClass:[NSArray class]]) {
NSLog(@"❌ Invalid project list format");
return;
}
if (!error) {
NSString *rawURL = data[@"Data"][@"url_path"];
NSString *baseURL = rawURL;
// remove trailing slash if exists
if ([baseURL hasSuffix:@"/"]) {
baseURL = [baseURL substringToIndex:baseURL.length - 1];
}
// append /api
baseURL = [baseURL stringByAppendingString:@"/api"];
NSLog(@"baseURL: %@", baseURL);
// [APIConfig setBaseURL:baseURL];
}
}];
}
#pragma mark - Helper
- (void)handleMenuButtonTapped {
NSLog(@"🍔 Menu button tapped");
......
......@@ -10,4 +10,8 @@
@property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *user_token;
@property (nonatomic, copy) NSString *projectId;
@property (nonatomic, copy) NSString *projectName;
@property (nonatomic, copy) NSArray *units;
@end
// UnitViewController.mm
#import "UnitViewController.h"
#import "DashboardViewController.h"
@interface UnitViewController () <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate>
@interface UnitViewController ()
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UISearchBar *searchBar;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, copy) NSArray *filteredUnits;
@end
@implementation UnitViewController
......@@ -13,7 +21,29 @@
[super viewDidLoad];
self.view.backgroundColor = UIColor.systemBackgroundColor;
self.filteredUnits = self.units;
if (self.filteredUnits.count == 1){
NSDictionary *unit = self.filteredUnits.firstObject;
dispatch_async(dispatch_get_main_queue(), ^{
[self openUnit:unit];
});
}
[self setupHeader];
[self setupSearchBar];
[self setupTableView];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.navigationController.navigationBarHidden = YES;
}
#pragma mark - Header Setup
......@@ -34,7 +64,7 @@
[self.headerView addSubview:self.backButton];
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.text = @"Unit";
self.titleLabel.text = self.projectName ?: @"";
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.font = [UIFont boldSystemFontOfSize:18];
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
......@@ -68,9 +98,152 @@
]];
}
#pragma mark - Search Bar
- (void)setupSearchBar {
self.searchBar = [[UISearchBar alloc] init];
self.searchBar.placeholder = @"Search";
self.searchBar.searchBarStyle = UISearchBarStyleMinimal;
self.searchBar.delegate = self;
self.searchBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.searchBar];
[NSLayoutConstraint activateConstraints:@[
[self.searchBar.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:8],
[self.searchBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.searchBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.searchBar.heightAnchor constraintEqualToConstant:44]
]];
}
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
self.filteredUnits = self.units;
} else {
NSPredicate *predicate =
[NSPredicate predicateWithBlock:^BOOL(NSDictionary *unit, NSDictionary *bindings) {
NSString *name = unit[@"unit"] ?: @"";
return [name localizedCaseInsensitiveContainsString:searchText];
}];
self.filteredUnits = [self.units filteredArrayUsingPredicate:predicate];
}
[self.tableView reloadData];
}
#pragma mark - Table View
- (void)setupTableView {
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero
style:UITableViewStylePlain];
self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundColor = UIColor.systemBackgroundColor;
[self.tableView registerClass:UITableViewCell.class
forCellReuseIdentifier:@"UnitCell"];
[self.view addSubview:self.tableView];
[NSLayoutConstraint activateConstraints:@[
[self.tableView.topAnchor constraintEqualToAnchor:self.searchBar.bottomAnchor constant:8],
[self.tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
]];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.filteredUnits.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:@"UnitCell"
forIndexPath:indexPath];
// ---- Reset reused cell ----
for (UIView *subview in cell.contentView.subviews) {
[subview removeFromSuperview];
}
NSDictionary *unit = self.filteredUnits[indexPath.row];
// ---- Label ----
UILabel *label = [[UILabel alloc] init];
label.text = unit[@"unit"] ?: unit[@"name"] ?: @"";
label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
label.translatesAutoresizingMaskIntoConstraints = NO;
// ---- Arrow ----
UIImageView *arrow = [[UIImageView alloc] initWithImage:
[UIImage systemImageNamed:@"chevron.right"]];
arrow.tintColor = UIColor.systemGrayColor;
arrow.translatesAutoresizingMaskIntoConstraints = NO;
// ---- Card styling ----
cell.backgroundColor = UIColor.clearColor;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.contentView.backgroundColor = UIColor.whiteColor;
cell.contentView.layer.cornerRadius = 12;
cell.contentView.layer.borderWidth = 1;
cell.contentView.layer.borderColor = UIColor.systemGray4Color.CGColor;
cell.contentView.clipsToBounds = YES;
// ---- Add views ----
[cell.contentView addSubview:label];
[cell.contentView addSubview:arrow];
// ---- Constraints ----
[NSLayoutConstraint activateConstraints:@[
// Label
[label.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:16],
[label.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor],
[label.trailingAnchor constraintEqualToAnchor:arrow.leadingAnchor constant:-8],
// Arrow
[arrow.trailingAnchor constraintEqualToAnchor:cell.contentView.trailingAnchor constant:-12],
[arrow.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor],
[arrow.widthAnchor constraintEqualToConstant:12],
[arrow.heightAnchor constraintEqualToConstant:18],
]];
return cell;
}
- (void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.contentView.frame =
CGRectInset(cell.contentView.frame, 16, 8);
}
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 64;
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *unit = self.filteredUnits[indexPath.row];
NSLog(@"🏠 Selected unit: %@", unit[@"unit"]);
[self openUnit:unit];
}
#pragma mark - Helper
- (void)onBack {
[self dismissViewControllerAnimated:YES completion:nil];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)handleMenuButtonTapped {
......@@ -78,8 +251,24 @@
if (self.drawerController) {
[self.drawerController toggleDrawer];
} else {
NSLog(@"⚠️ drawerController not set on DashboardViewController");
NSLog(@"⚠️ drawerController not set on UnitViewController");
}
}
- (void)openUnit:(NSDictionary *)unit {
NSLog(@"🏠 Auto-opening unit: %@", unit[@"unit"]);
NSString *projectId = [unit[@"project_id"] description];
NSString *drawingPlanId = [unit[@"id"] description];
DashboardViewController *vc = [[DashboardViewController alloc] init];
vc.projectCode = unit[@"name"] ?: @"";
vc.projectName = self.projectName;
vc.projectId = projectId ?: @"";
vc.drawingPlanId = drawingPlanId ?: @"";
vc.drawerController = self.drawerController;
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self.navigationController pushViewController:vc animated:YES];
}
@end
......@@ -710,7 +710,6 @@
- (void)handleSettingsByLocation:(NSString *)locationID planID:(NSString *)planID {
[APIClient requestSettingsByLocation:locationID
projectID:@"8"
completion:^(NSDictionary *data, NSError *error) {
if (error) {
NSLog(@"❌ Error requesting settings: %@", error);
......
......@@ -36,16 +36,15 @@
clientCode:clientCode
userToken:userToken];
// 5️⃣ Inject drawerController reference into all screens
// 5️⃣ Assign main content (nav) to drawerController
[drawerController setValue:nav forKey:@"_mainVC"];
// 6️⃣ Inject drawerController reference into all screens
project.drawerController = drawerController;
unit.drawerController = drawerController;
dashboard.drawerController = drawerController;
// 6️⃣ Replace mainVC in DrawerController with nav
[drawerController setValue:nav forKey:@"_mainVC"]; // or update your property to accept UINavigationController
return drawerController;
}
@end
......@@ -6,13 +6,11 @@ NS_ASSUME_NONNULL_BEGIN
@interface APIClient : NSObject
+ (void)requestAccessItem:(NSString *)unitId
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion;
+ (void)requestAccessItem:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion;
+ (void)requestGetUnitPlan:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)requestSettingsByLocation:(NSString * _Nonnull)locationID
projectID:(NSString * _Nonnull)projectID
completion:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)submitAddIssue:(NSDictionary * _Nonnull)params
......@@ -79,6 +77,9 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)downloadAndCacheImage:(NSURL *)url
completion:(void (^)(BOOL success))completion;
+ (void)requestCompanyCode:(NSString *)companyCode
completion:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
@end
NS_ASSUME_NONNULL_END
......@@ -4,8 +4,7 @@
@implementation APIClient
+ (void)requestAccessItem:(NSString *)unitId
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
+ (void)requestAccessItem:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getAccessItem"];
......@@ -15,8 +14,8 @@
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"drawing_plan_id": unitId ?: @"",
@"os": [APIConfig os] ,
@"drawing_plan_id": [APIConfig drawingPlanId] ?: @"",
@"information": [APIConfig deviceInfo],
}
};
......@@ -97,8 +96,8 @@
};
// 🧩 Add POST fields
appendFormField(@"data[os]", @"AND");
appendFormField(@"data[drawing_plan_id]",@"135");
appendFormField(@"data[os]", [APIConfig os] );
appendFormField(@"data[drawing_plan_id]",[APIConfig drawingPlanId] );
// You can reuse your existing getDeviceInfo() method to produce this JSON string
NSString *deviceInfo = [APIConfig deviceInfoJSONString];
......@@ -156,7 +155,6 @@
}
+ (void)requestSettingsByLocation:(NSString *)locationID
projectID:(NSString *)projectID
completion:(void (^)(NSDictionary *data, NSError *error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getGeneralSettingByLocation"];
......@@ -183,8 +181,8 @@
};
// 🧩 Add POST fields
appendFormField(@"data[os]", @"AND");
appendFormField(@"data[project_id]", projectID ?: @"0");
appendFormField(@"data[os]", [APIConfig os] );
appendFormField(@"data[project_id]", [APIConfig projectId] ?: @"0");
appendFormField(@"data[location_id]", locationID ?: @"0");
NSString *deviceInfo = [APIConfig deviceInfoJSONString];
......@@ -277,7 +275,7 @@
}
// 🔹 Append OS info
appendFormField(@"data[os]", @"AND");
appendFormField(@"data[os]", [APIConfig os] );
// 🔹 Append images
if (images.count > 0) {
......@@ -371,7 +369,7 @@
}
// 🔹 Always include OS
appendFormField(@"data[plan_id]", @"135");
appendFormField(@"data[plan_id]", [APIConfig drawingPlanId] );
appendFormField(@"data[location_id]", updateData[@"location_id"]);
appendFormField(@"data[issue_id]", updateData[@"issue_id"]);
appendFormField(@"data[issue_setting_id]", updateData[@"issue_setting_id"]);
......@@ -455,9 +453,9 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"project_id": @"8",
@"drawing_plan_id": @"135"
@"os": [APIConfig os] ,
@"project_id": [APIConfig projectId] ,
@"drawing_plan_id": [APIConfig drawingPlanId]
}
};
......@@ -519,8 +517,8 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"drawing_plan_id": @"135"
@"os": [APIConfig os] ,
@"drawing_plan_id": [APIConfig drawingPlanId]
}
};
......@@ -708,7 +706,7 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"project_id": @"8",
@"project_id": [APIConfig projectId] ,
@"appointment_id": appointmentId,
@"reason": reason
}
......@@ -779,8 +777,8 @@
};
// Add form fields
appendFormField(@"data[os]", @"AND");
appendFormField(@"data[drawing_plan_id]", @"135");
appendFormField(@"data[os]", [APIConfig os] );
appendFormField(@"data[drawing_plan_id]", [APIConfig drawingPlanId] );
NSString *infoJson = @"{\"OS\":\"AND\",\"IMEI\":\"AND:2a2f13ff17b1cbb5\",\"OS_VERSION\":\"35\",\"MODEL\":\"2306EPN60G\",\"APP_VERSION\":\"1.22.26\"}";
appendFormField(@"data[information]", infoJson);
......@@ -836,8 +834,8 @@
};
// Add form fields (same as DashboardInfo)
appendFormField(@"data[os]", @"AND");
appendFormField(@"data[project_id]", @"8");
appendFormField(@"data[os]", [APIConfig os] );
appendFormField(@"data[project_id]", [APIConfig projectId] );
appendFormField(@"data[client_id]", @"3");
NSString *infoJson = @"{\"OS\":\"AND\",\"IMEI\":\"AND:2a2f13ff17b1cbb5\",\"OS_VERSION\":\"35\",\"MODEL\":\"2306EPN60G\",\"APP_VERSION\":\"1.22.26\"}";
......@@ -897,7 +895,7 @@
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"os": [APIConfig os] ,
@"issue_id": issueID,
@"information": [APIConfig deviceInfo],
}
......@@ -964,7 +962,7 @@
@"data": @{
@"issue_id": issueID,
@"remarks": remarks,
@"os": @"AND",
@"os": [APIConfig os] ,
@"full_response": @"false",
@"information": [APIConfig deviceInfo],
}
......@@ -1045,7 +1043,7 @@
// 🔹 Append OS info
appendFormField(@"data[issue_id]", issueID ?: @"");
appendFormField(@"data[remarks]", remarks ?: @"");
appendFormField(@"data[os]", @"AND");
appendFormField(@"data[os]", [APIConfig os] );
// 🔹 Append images
if (images.count > 0) {
......@@ -1145,8 +1143,8 @@
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"drawing_plan_id": @"135",
@"os": [APIConfig os] ,
@"drawing_plan_id": [APIConfig drawingPlanId] ,
@"information": [APIConfig deviceInfo],
}
};
......@@ -1218,7 +1216,7 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"os": [APIConfig os] ,
@"issue_id": issueArray,
@"remarks": remarksSafe
}
......@@ -1284,7 +1282,7 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"os": [APIConfig os] ,
@"issue_id": issueID ?: @"",
@"remarks": remarks ?: @""
}
......@@ -1348,8 +1346,8 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"project_id": @"8",
@"os": [APIConfig os] ,
@"project_id": [APIConfig projectId] ,
@"information": [APIConfig deviceInfo],
}
};
......@@ -1412,8 +1410,8 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"project_id": @"8",
@"os": [APIConfig os] ,
@"project_id": [APIConfig projectId] ,
@"information": [APIConfig deviceInfo]
}
};
......@@ -1476,9 +1474,9 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"project_id": @"8",
@"drawing_plan_id": @"135",
@"os": [APIConfig os] ,
@"project_id": [APIConfig projectId] ,
@"drawing_plan_id": [APIConfig drawingPlanId] ,
@"information": [APIConfig deviceInfo]
}
};
......@@ -1541,7 +1539,7 @@
// ✅ Build JSON body
NSDictionary *jsonBody = @{
@"data": @{
@"os": @"AND",
@"os": [APIConfig os] ,
}
};
......@@ -1722,6 +1720,69 @@
// [task resume];
// }
+ (void)requestCompanyCode:(NSString *)companyCode
completion:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; {
NSString *urlString = @"https://kitadev.commudesk.com/api/companycode/get";
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
NSDictionary *jsonBody = @{
@"data": @{
@"os": [APIConfig os],
@"company_code": companyCode.length > 0
? [companyCode lowercaseString]
: @"",
@"information": [APIConfig deviceInfo],
}
};
// ✅ Convert dictionary → NSData
NSError *jsonError;
NSData *bodyData = [NSJSONSerialization dataWithJSONObject:jsonBody options:0 error:&jsonError];
if (jsonError) {
NSLog(@"❌ JSON Serialization Error: %@", jsonError);
if (completion) completion(nil, jsonError);
return;
}
request.HTTPBody = bodyData;
// 🧭 Debug logs
NSLog(@"🌍 URL: %@", urlString);
NSLog(@"📦 Body JSON: %@", jsonBody);
// ✅ Make request
NSURLSessionDataTask *task = [[NSURLSession sharedSession]
dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"❌ Network Error: %@", error);
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(nil, error);
});
return;
}
NSError *jsonParseError;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParseError];
if (jsonParseError) {
NSLog(@"⚠️ JSON Parse Error: %@", jsonParseError);
} else {
NSLog(@"✅ Company Code API Response:\n%@", jsonResponse);
}
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(jsonResponse, jsonParseError);
});
}];
[task resume];
}
#pragma mark - Helper Methods
+ (NSString *)multipartFormField:(NSString *)name value:(NSString *)value boundary:(NSString *)boundary {
return [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"data[%@]\"\r\n\r\n%@\r\n", boundary, name, value];
......
......@@ -5,11 +5,24 @@ NS_ASSUME_NONNULL_BEGIN
@interface APIConfig : NSObject
//os
+ (NSString *)os;
/// Base API URL (no trailing slash)
+ (NSString *)baseURL;
+ (void)setBaseURL:(NSString *)baseURL;
//drawingplan
+ (NSString *)drawingPlanId;
+ (void)setDrawingPlanId:(NSString *)drawingPlanId;
//projectid
+ (NSString *)projectId;
+ (void)setProjectId:(NSString *)projectId;
/// Auth token (JWT)
+ (NSString *)authToken;
+ (void)setAuthTokem:(NSString *)authToken;
/// Convenience: baseURL + path + ?token=
+ (NSURL *)urlWithPath:(NSString *)path;
......
// APIConfig.mm
#import "APIConfig.h"
static NSString *kBaseURL = @"https://kitadev.commudesk.com/api";
static NSString *kDrawingPlanId = @"";
static NSString *kProjectId = @"";
static NSString *kAuthToken = @"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImF0aGlyYWh6YWlkaUBjb252ZXAuY29tIiwicGFzc3dvcmQiOiIkMnkkMTAkNU9xYklqMnZ6UHJwckJrcVd5c3I2LmJCc1hVYS9Hd014eUhnL3RhUUhPUkNQcGdmTG8yakciLCJzdWIiOjIxNzAsImlzcyI6Imh0dHBzOi8va2l0YWRldi5jb21tdWRlc2suY29tL2FwaS9vd25lci9hdXRoL3Bhc3N3b3JkbGVzc19sb2dpbiIsImlhdCI6MTc2MDMxNTM1MiwiZXhwIjoyMDc1ODg0ODcyLCJuYmYiOjE3NjAzMTUzNTIsImp0aSI6IktoQmNyQnJEdDVNdDZlWmMifQ.JnxGbZ7hTeoOr6oibIzZMphgyKtTo2Aq9Efx6mrGfFA";
@implementation APIConfig
#pragma mark - OS
+ (NSString *)os {
return @"AND";
}
#pragma mark - URL
+ (NSString *)baseURL {
return @"https://kitadev.commudesk.com/api";
return kBaseURL;
}
+ (void)setBaseURL:(NSString *)baseURL {
if (baseURL.length > 0) {
kBaseURL = [baseURL copy];
NSLog(@"🌐 API baseURL set to: %@", kBaseURL);
}
}
#pragma mark - Project Id
+ (NSString *)projectId {
return kProjectId;
}
+ (void)setProjectId:(NSString *)projectId {
if (projectId.length > 0) {
kProjectId = [projectId copy];
NSLog(@"🌐 API projectId set to: %@", kProjectId);
}
}
#pragma mark - Drawing Plan Id
+ (NSString *)drawingPlanId {
return kDrawingPlanId;
}
+ (void)setDrawingPlanId:(NSString *)drawingPlanId {
if (drawingPlanId.length > 0) {
kDrawingPlanId = [drawingPlanId copy];
NSLog(@"🌐 API drawing plan id set to: %@", kDrawingPlanId);
}
}
#pragma mark - AuthToken
+ (NSString *)authToken {
return @"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImF0aGlyYWh6YWlkaUBjb252ZXAuY29tIiwicGFzc3dvcmQiOiIkMnkkMTAkNU9xYklqMnZ6UHJwckJrcVd5c3I2LmJCc1hVYS9Hd014eUhnL3RhUUhPUkNQcGdmTG8yakciLCJzdWIiOjIxNzAsImlzcyI6Imh0dHBzOi8va2l0YWRldi5jb21tdWRlc2suY29tL2FwaS9vd25lci9hdXRoL3Bhc3N3b3JkbGVzc19sb2dpbiIsImlhdCI6MTc2MDMxNTM1MiwiZXhwIjoyMDc1ODg0ODcyLCJuYmYiOjE3NjAzMTUzNTIsImp0aSI6IktoQmNyQnJEdDVNdDZlWmMifQ.JnxGbZ7hTeoOr6oibIzZMphgyKtTo2Aq9Efx6mrGfFA";
return kAuthToken;
}
+ (void)setAuthTokem:(NSString *)authToken {
if (authToken.length > 0) {
kAuthToken = [authToken copy];
NSLog(@"🌐 API drawing plan id set to: %@", kAuthToken);
}
}
+ (NSURL *)urlWithPath:(NSString *)path {
......@@ -22,7 +71,8 @@
+ (NSDictionary<NSString *, NSString *> *)deviceInfo {
return @{
@"OS": @"AND",
@"OS": [self os],
@"drawing_plan_id": [self drawingPlanId],
@"IMEI": @"AND:2a2f13ff17b1cbb5",
@"OS_VERSION": @"35",
@"MODEL": @"2306EPN60G",
......
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
QmsRootView()
.ignoresSafeArea() // important for navigation & drawer
}
}
#Preview {
ContentView()
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
// QmRootView.swift
import SwiftUI
import QmsPluginFramework
struct QmsRootView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
return QmsPluginUI.makeViewController()
}
func updateUIViewController(
_ uiViewController: UIViewController,
context: Context
) {
// no-op
}
}
// testAppApp.swift
import SwiftUI
@main
struct testAppApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
......@@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment