Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
weihan-plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Wei Han
weihan-plugin
Commits
3995f152
Commit
3995f152
authored
Jan 14, 2026
by
Wei Han
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code update
parent
91919501
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
381 additions
and
280 deletions
+381
-280
Info.plist
...PluginFramework/QmsPluginFramework.xcframework/Info.plist
+5
-5
QmsPluginFramework
...ios-arm64/QmsPluginFramework.framework/QmsPluginFramework
+0
-0
QmsPluginFramework
...simulator/QmsPluginFramework.framework/QmsPluginFramework
+0
-0
DashboardViewController.mm
...k/QmsPluginFramework/Dashboard/DashboardViewController.mm
+199
-147
GeneralInfoViewController.mm
...QmsPluginFramework/Dashboard/GeneralInfoViewController.mm
+15
-10
ProjectViewController.mm
...ork/QmsPluginFramework/Dashboard/ProjectViewController.mm
+28
-31
UnitViewController.mm
...mework/QmsPluginFramework/Dashboard/UnitViewController.mm
+34
-20
HistoryViewController.mm
...amework/QmsPluginFramework/Issue/HistoryViewController.mm
+1
-2
IssuesViewController.mm
...ramework/QmsPluginFramework/Issue/IssuesViewController.mm
+14
-13
SyncProjectViewController.mm
...work/QmsPluginFramework/Sync/SyncProjectViewController.mm
+0
-2
SyncScreenViewController.mm
...ework/QmsPluginFramework/Sync/SyncScreenViewController.mm
+1
-2
APIClient.mm
...inFramework/QmsPluginFramework/Utilities/API/APIClient.mm
+23
-23
APIConfig.mm
...inFramework/QmsPluginFramework/Utilities/API/APIConfig.mm
+2
-2
QmsDashboardViewManager.mm
ios/QmsPlugin/QmsDashboardViewManager.mm
+54
-18
Info.plist
ios/QmsPluginFramework.xcframework/Info.plist
+5
-5
QmsPluginFramework
...ios-arm64/QmsPluginFramework.framework/QmsPluginFramework
+0
-0
QmsPluginFramework
...simulator/QmsPluginFramework.framework/QmsPluginFramework
+0
-0
No files found.
framework/QmsPluginFramework/QmsPluginFramework.xcframework/Info.plist
View file @
3995f152
...
@@ -8,32 +8,32 @@
...
@@ -8,32 +8,32 @@
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
string
>
ios-arm64
_x86_64-simulator
<
/string
>
<
string
>
ios-arm64
<
/string
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
a
rr
a
y
>
<
a
rr
a
y
>
<
string
>
arm64
<
/string
>
<
string
>
arm64
<
/string
>
<
string
>
x86_64
<
/string
>
<
/
a
rr
a
y
>
<
/
a
rr
a
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
string
>
ios
<
/string
>
<
string
>
ios
<
/string
>
<
k
e
y
>
SupportedPlatformVariant
<
/k
e
y
>
<
string
>
simulator
<
/string
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
string
>
ios-arm64
<
/string
>
<
string
>
ios-arm64
_x86_64-simulator
<
/string
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
a
rr
a
y
>
<
a
rr
a
y
>
<
string
>
arm64
<
/string
>
<
string
>
arm64
<
/string
>
<
string
>
x86_64
<
/string
>
<
/
a
rr
a
y
>
<
/
a
rr
a
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
string
>
ios
<
/string
>
<
string
>
ios
<
/string
>
<
k
e
y
>
SupportedPlatformVariant
<
/k
e
y
>
<
string
>
simulator
<
/string
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
/
a
rr
a
y
>
<
/
a
rr
a
y
>
<
k
e
y
>
CFBundlePackageType
<
/k
e
y
>
<
k
e
y
>
CFBundlePackageType
<
/k
e
y
>
...
...
framework/QmsPluginFramework/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/QmsPluginFramework
View file @
3995f152
No preview for this file type
framework/QmsPluginFramework/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/QmsPluginFramework
View file @
3995f152
No preview for this file type
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/DashboardViewController.mm
View file @
3995f152
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
#import "APIConfig.h"
#import "APIConfig.h"
#import "ImageCacheHelper.h"
#import "ImageCacheHelper.h"
@interface DashboardViewController ()
@interface DashboardViewController ()
<UIScrollViewDelegate>
@property (nonatomic, strong) NSArray *appointments;
@property (nonatomic, strong) NSArray *appointments;
@property (nonatomic, strong) NSArray *issues;
@property (nonatomic, strong) NSArray *issues;
...
@@ -44,11 +44,14 @@
...
@@ -44,11 +44,14 @@
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UIButton *backButton;
@property (nonatomic, strong) UIStackView *contentContainer;
@property (nonatomic, strong) UIStackView *contentContainer;
@property (nonatomic, strong) UIView *inspectionBanner;
@property (nonatomic, strong) UIView *inspectionBanner;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIView *contentView;
@property (nonatomic, strong) UIView *stickyBar;
@end
@end
@implementation DashboardViewController {
@implementation DashboardViewController {
UIScrollView *_scrollView;
NSMutableDictionary *_sectionViews;
NSMutableDictionary *_sectionViews;
CGFloat _currentY;
CGFloat _currentY;
}
}
...
@@ -57,16 +60,17 @@
...
@@ -57,16 +60,17 @@
[super viewDidLoad];
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
_sectionViews = [NSMutableDictionary dictionary];
_sectionViews = [NSMutableDictionary dictionary];
[self setupScrollView];
[self setupStickyBar];
[self setupHeader];
[self setupHeader];
[self setupScrollContent];
[self setupScrollContent];
[self setupFooter];
[self setupFooter];
[self showLoadingOverlay:@"Loading dashboard..."];
[self showLoadingOverlay:@"Loading dashboard..."];
NSLog(@"dashboard.drawerController = %@", self.drawerController);
NSLog(@"dashboard.drawerController = %@", self.drawerController);
//
[[OfflineSyncManager shared] clearOfflineQueue];
//
[[OfflineSyncManager shared] clearOfflineQueue];
}
}
- (void)viewWillAppear:(BOOL)animated {
- (void)viewWillAppear:(BOOL)animated {
...
@@ -125,35 +129,95 @@
...
@@ -125,35 +129,95 @@
}
}
#pragma mark - Layout
#pragma mark - Layout
- (void)viewDidLayoutSubviews {
//
- (void)viewDidLayoutSubviews {
NSLog(@"Header frame: %@", NSStringFromCGRect(_headerView.frame));
//
NSLog(@"Header frame: %@", NSStringFromCGRect(_headerView.frame));
[super viewDidLayoutSubviews];
//
[super viewDidLayoutSubviews];
UIView *footerView = self.view.subviews.lastObject;
//
UIView *footerView = self.view.subviews.lastObject;
CGFloat footerHeight = 80.0;
//
CGFloat footerHeight = 80.0;
CGFloat bottomInset = self.view.safeAreaInsets.bottom;
//
CGFloat bottomInset = self.view.safeAreaInsets.bottom;
footerView.frame = CGRectMake(
//
footerView.frame = CGRectMake(
0,
//
0,
self.view.bounds.size.height - footerHeight - bottomInset,
//
self.view.bounds.size.height - footerHeight - bottomInset,
self.view.bounds.size.width,
//
self.view.bounds.size.width,
footerHeight + bottomInset
//
footerHeight + bottomInset
);
//
);
}
//
}
#pragma mark - Header
#pragma mark - Header
- (void)setupStickyBar {
self.stickyBar = [[UIView alloc] init];
self.stickyBar.translatesAutoresizingMaskIntoConstraints = NO;
self.stickyBar.backgroundColor = [UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:0]; // start fully transparent
[self.view addSubview:self.stickyBar];
[NSLayoutConstraint activateConstraints:@[
[self.stickyBar.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.stickyBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.stickyBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.stickyBar.heightAnchor constraintEqualToConstant:44]
]];
// Back button
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"]
forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self action:@selector(onBack)
forControlEvents:UIControlEventTouchUpInside];
[self.stickyBar addSubview:self.backButton];
// Menu button
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
menuButton.translatesAutoresizingMaskIntoConstraints = NO;
[menuButton setImage:[UIImage systemImageNamed:@"line.horizontal.3"]
forState:UIControlStateNormal];
menuButton.tintColor = UIColor.whiteColor;
[menuButton addTarget:self
action:@selector(handleMenuButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
[self.stickyBar addSubview:menuButton];
[NSLayoutConstraint activateConstraints:@[
[self.backButton.leadingAnchor constraintEqualToAnchor:self.stickyBar.leadingAnchor constant:8],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.stickyBar.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:24],
[self.backButton.heightAnchor constraintEqualToConstant:24],
[menuButton.trailingAnchor constraintEqualToAnchor:self.stickyBar.trailingAnchor constant:-16],
[menuButton.centerYAnchor constraintEqualToAnchor:self.stickyBar.centerYAnchor],
[menuButton.widthAnchor constraintEqualToConstant:26],
[menuButton.heightAnchor constraintEqualToConstant:26],
]];
UIView *statusBarBackground = [[UIView alloc] init];
statusBarBackground.translatesAutoresizingMaskIntoConstraints = NO;
statusBarBackground.backgroundColor =
[UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:1.0];
[self.view insertSubview:statusBarBackground aboveSubview:self.scrollView];
[NSLayoutConstraint activateConstraints:@[
[statusBarBackground.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[statusBarBackground.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[statusBarBackground.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[statusBarBackground.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
]];
}
- (void)setupHeader {
- (void)setupHeader {
CGFloat headerHeight = 2
20
.0;
CGFloat headerHeight = 2
55
.0;
CGFloat maxImageHeight = 2
20
.0;
CGFloat maxImageHeight = 2
55
.0;
// ---------- Header Container ----------
// ---------- Header Container ----------
self.headerView = [[UIView alloc] init];
self.headerView = [[UIView alloc] init];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
self.headerView.backgroundColor = [UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:1.0];
self.headerView.backgroundColor = [UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:1.0];
[self.
v
iew addSubview:self.headerView];
[self.
contentV
iew addSubview:self.headerView];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[self.headerView.topAnchor constraintEqualToAnchor:self.
v
iew.topAnchor],
[self.headerView.topAnchor constraintEqualToAnchor:self.
contentV
iew.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.
v
iew.leadingAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.
contentV
iew.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.
v
iew.trailingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.
contentV
iew.trailingAnchor],
[self.headerView.heightAnchor constraintEqualToConstant:headerHeight]
[self.headerView.heightAnchor constraintEqualToConstant:headerHeight]
]];
]];
...
@@ -188,7 +252,7 @@
...
@@ -188,7 +252,7 @@
self.overlayImageView.translatesAutoresizingMaskIntoConstraints = NO;
self.overlayImageView.translatesAutoresizingMaskIntoConstraints = NO;
self.overlayImageView.contentMode = UIViewContentModeScaleToFill;
self.overlayImageView.contentMode = UIViewContentModeScaleToFill;
self.overlayImageView.userInteractionEnabled = NO;
self.overlayImageView.userInteractionEnabled = NO;
self.overlayImageView.alpha = 0.5;
//
self.overlayImageView.alpha = 0.5;
[imageContainer addSubview:self.overlayImageView];
[imageContainer addSubview:self.overlayImageView];
...
@@ -199,59 +263,17 @@
...
@@ -199,59 +263,17 @@
[self.overlayImageView.bottomAnchor constraintEqualToAnchor:imageContainer.bottomAnchor]
[self.overlayImageView.bottomAnchor constraintEqualToAnchor:imageContainer.bottomAnchor]
]];
]];
// ---------- Header Bar (Top) ----------
UIView *headerBar = [[UIView alloc] init];
headerBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:headerBar];
[NSLayoutConstraint activateConstraints:@[
[headerBar.topAnchor constraintEqualToAnchor:self.headerView.safeAreaLayoutGuide.topAnchor],
[headerBar.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor],
[headerBar.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor],
[headerBar.heightAnchor constraintEqualToConstant:44]
]];
// ---------- Project Name ----------
// ---------- Project Name ----------
self.projectNameLabel = [[UILabel alloc] init];
self.projectNameLabel = [[UILabel alloc] init];
self.projectNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.projectNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.projectNameLabel.font = [UIFont boldSystemFontOfSize:18];
self.projectNameLabel.font = [UIFont boldSystemFontOfSize:18];
self.projectNameLabel.textColor = UIColor.whiteColor;
self.projectNameLabel.textColor = UIColor.whiteColor;
self.projectNameLabel.textAlignment = NSTextAlignmentCenter;
self.projectNameLabel.textAlignment = NSTextAlignmentCenter;
[
headerBa
r addSubview:self.projectNameLabel];
[
imageContaine
r addSubview:self.projectNameLabel];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[self.projectNameLabel.centerXAnchor constraintEqualToAnchor:headerBar.centerXAnchor],
[self.projectNameLabel.centerXAnchor constraintEqualToAnchor:self.stickyBar.centerXAnchor],
[self.projectNameLabel.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor]
[self.projectNameLabel.centerYAnchor constraintEqualToAnchor:self.stickyBar.centerYAnchor]
]];
// ---------- Menu Button ----------
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
menuButton.translatesAutoresizingMaskIntoConstraints = NO;
[menuButton setImage:[UIImage systemImageNamed:@"line.horizontal.3"] forState:UIControlStateNormal];
menuButton.tintColor = UIColor.whiteColor;
[menuButton addTarget:self action:@selector(handleMenuButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[headerBar addSubview:menuButton];
[NSLayoutConstraint activateConstraints:@[
[menuButton.trailingAnchor constraintEqualToAnchor:headerBar.trailingAnchor constant:-16],
[menuButton.centerYAnchor constraintEqualToAnchor:headerBar.centerYAnchor],
[menuButton.widthAnchor constraintEqualToConstant:26],
[menuButton.heightAnchor constraintEqualToConstant:26]
]];
// ---------- Back Button ----------
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.backButton setImage:[UIImage systemImageNamed:@"chevron.backward"] forState:UIControlStateNormal];
self.backButton.tintColor = UIColor.whiteColor;
[self.backButton addTarget:self action:@selector(onBack) forControlEvents:UIControlEventTouchUpInside];
[headerBar 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]
]];
]];
// ---------- Unit Name ----------
// ---------- Unit Name ----------
...
@@ -280,6 +302,21 @@
...
@@ -280,6 +302,21 @@
[self.infoButton.widthAnchor constraintEqualToConstant:24],
[self.infoButton.widthAnchor constraintEqualToConstant:24],
[self.infoButton.heightAnchor constraintEqualToConstant:24]
[self.infoButton.heightAnchor constraintEqualToConstant:24]
]];
]];
// ---------- Dark Overlay ----------
UIView *darkOverlay = [[UIView alloc] init];
darkOverlay.translatesAutoresizingMaskIntoConstraints = NO;
darkOverlay.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.35];
darkOverlay.userInteractionEnabled = NO;
[imageContainer addSubview:darkOverlay];
[NSLayoutConstraint activateConstraints:@[
[darkOverlay.topAnchor constraintEqualToAnchor:imageContainer.topAnchor],
[darkOverlay.leadingAnchor constraintEqualToAnchor:imageContainer.leadingAnchor],
[darkOverlay.trailingAnchor constraintEqualToAnchor:imageContainer.trailingAnchor],
[darkOverlay.bottomAnchor constraintEqualToAnchor:imageContainer.bottomAnchor]
]];
// ---------- Load Remote Image & Overlay ----------
// ---------- Load Remote Image & Overlay ----------
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
...
@@ -297,7 +334,10 @@
...
@@ -297,7 +334,10 @@
NSURL *url = [NSURL URLWithString:remoteHeaderURL];
NSURL *url = [NSURL URLWithString:remoteHeaderURL];
[ImageCacheHelper loadImageWithURL:url completion:^(UIImage *image) {
[ImageCacheHelper loadImageWithURL:url completion:^(UIImage *image) {
self.backgroundImageView.image = image ?: [UIImage imageNamed:@"header_bg"];
self.backgroundImageView.image = image ?: [UIImage imageNamed:@"header_bg"];
[imageContainer bringSubviewToFront:self.backgroundImageView];
[imageContainer bringSubviewToFront:darkOverlay];
[imageContainer bringSubviewToFront:self.overlayImageView];
[imageContainer bringSubviewToFront:self.overlayImageView];
[imageContainer bringSubviewToFront:self.projectNameLabel];
}];
}];
} else {
} else {
self.backgroundImageView.image = [UIImage imageNamed:@"header_bg"];
self.backgroundImageView.image = [UIImage imageNamed:@"header_bg"];
...
@@ -307,7 +347,7 @@
...
@@ -307,7 +347,7 @@
#pragma mark - Footer
#pragma mark - Footer
- (void)setupFooter {
- (void)setupFooter {
CGFloat footerHeight =
80
.0;
CGFloat footerHeight =
72
.0;
CGFloat bottomInset = self.view.safeAreaInsets.bottom;
CGFloat bottomInset = self.view.safeAreaInsets.bottom;
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(
0,
0,
...
@@ -320,9 +360,13 @@
...
@@ -320,9 +360,13 @@
footerView.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
footerView.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
footerView.layer.shadowOpacity = 0.8;
footerView.layer.shadowOpacity = 0.8;
footerView.layer.shadowOffset = CGSizeMake(0, -1);
footerView.layer.shadowOffset = CGSizeMake(0, -1);
footerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
footerView.layer.cornerRadius = 16.0;
footerView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; // top-left & top-right
footerView.clipsToBounds = YES;
[self.view addSubview:footerView];
[self.view addSubview:footerView];
NSArray *titles = @[ @"Make App
ointment", @"Add Issue", @"View
Access Item" ];
NSArray *titles = @[ @"Make App
t.", @"Add Issue", @"
Access Item" ];
NSArray *icons = @[ @"calendar", @"plus.circle", @"list.bullet" ];
NSArray *icons = @[ @"calendar", @"plus.circle", @"list.bullet" ];
CGFloat buttonWidth = self.view.bounds.size.width / titles.count;
CGFloat buttonWidth = self.view.bounds.size.width / titles.count;
...
@@ -330,9 +374,9 @@
...
@@ -330,9 +374,9 @@
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(i * buttonWidth, 0, buttonWidth, footerHeight);
button.frame = CGRectMake(i * buttonWidth, 0, buttonWidth, footerHeight);
[button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor
colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0
] forState:UIControlStateNormal];
[button setTitleColor:[UIColor
whiteColor
] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:13];
button.titleLabel.font = [UIFont boldSystemFontOfSize:13];
button.tintColor = [UIColor
colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0
];
button.tintColor = [UIColor
whiteColor
];
[button setImage:[UIImage systemImageNamed:icons[i]] forState:UIControlStateNormal];
[button setImage:[UIImage systemImageNamed:icons[i]] forState:UIControlStateNormal];
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
...
@@ -391,73 +435,64 @@
...
@@ -391,73 +435,64 @@
}
}
#pragma mark - Scroll Content
#pragma mark - Scroll Content
- (void)setupScrollContent {
- (void)setupScrollView {
// ScrollView
self.scrollView = [[UIScrollView alloc] init];
_scrollView = [[UIScrollView alloc] init];
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
_scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.scrollView.alwaysBounceVertical = YES;
_scrollView.alwaysBounceVertical = YES;
self.scrollView.delegate = self;
[self.view addSubview:_scrollView];
[self.view addSubview:self.scrollView];
CGFloat footerHeight = 80.0;
self.contentView = [[UIView alloc] init];
self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:self.contentView];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[_scrollView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor],
[self.scrollView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[_scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[_scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[_scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-footerHeight]
[self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
[self.contentView.topAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.topAnchor],
[self.contentView.leadingAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.leadingAnchor],
[self.contentView.trailingAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.trailingAnchor],
[self.contentView.bottomAnchor constraintEqualToAnchor:self.scrollView.contentLayoutGuide.bottomAnchor],
[self.contentView.widthAnchor constraintEqualToAnchor:self.scrollView.frameLayoutGuide.widthAnchor],
]];
]];
}
- (void)setupScrollContent {
UIView *banner = [self buildInspectionChecklistBanner];
UIView *banner = [self buildInspectionChecklistBanner];
UIView *stackContainer = [[UIView alloc] init];
stackContainer.translatesAutoresizingMaskIntoConstraints = NO;
[_scrollView addSubview:stackContainer];
CGFloat topOffset = 16;
CGFloat topOffset = 16;
if (banner) {
if (banner) {
banner.translatesAutoresizingMaskIntoConstraints = NO;
banner.translatesAutoresizingMaskIntoConstraints = NO;
[_scroll
View addSubview:banner];
[self.content
View addSubview:banner];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[banner.topAnchor constraintEqualToAnchor:_scrollView.contentLayoutGuide.top
Anchor constant:topOffset],
[banner.topAnchor constraintEqualToAnchor:self.headerView.bottom
Anchor constant:topOffset],
[banner.leadingAnchor constraintEqualToAnchor:_scroll
View.leadingAnchor constant:16],
[banner.leadingAnchor constraintEqualToAnchor:self.content
View.leadingAnchor constant:16],
[banner.trailingAnchor constraintEqualToAnchor:_scroll
View.trailingAnchor constant:-16],
[banner.trailingAnchor constraintEqualToAnchor:self.content
View.trailingAnchor constant:-16],
[banner.heightAnchor constraintEqualToConstant:90]
[banner.heightAnchor constraintEqualToConstant:90]
]];
]];
topOffset += 90 + 16; // stack starts after banner + spacing
topOffset += 90 + 16;
}
}
// Content container (STACK VIEW)
UIStackView *stack = [[UIStackView alloc] init];
UIStackView *stack = [[UIStackView alloc] init];
stack.axis = UILayoutConstraintAxisVertical;
stack.axis = UILayoutConstraintAxisVertical;
stack.spacing =
16
;
stack.spacing =
22
;
stack.translatesAutoresizingMaskIntoConstraints = NO;
stack.translatesAutoresizingMaskIntoConstraints = NO;
stack.layoutMargins = UIEdgeInsetsMake(0, 16, 16, 16);
stack.layoutMargins = UIEdgeInsetsMake(0, 16, 16, 16);
stack.layoutMarginsRelativeArrangement = YES;
stack.layoutMarginsRelativeArrangement = YES;
[s
tackContainer
addSubview:stack];
[s
elf.contentView
addSubview:stack];
self.contentContainer = stack;
self.contentContainer = stack;
[NSLayoutConstraint activateConstraints:@[
[stack.topAnchor constraintEqualToAnchor:stackContainer.topAnchor],
[stack.leadingAnchor constraintEqualToAnchor:stackContainer.leadingAnchor],
[stack.trailingAnchor constraintEqualToAnchor:stackContainer.trailingAnchor],
[stack.bottomAnchor constraintEqualToAnchor:stackContainer.bottomAnchor],
[stack.widthAnchor constraintEqualToAnchor:stackContainer.widthAnchor]
]];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
// Top/bottom for vertical scrolling
[stack.topAnchor constraintEqualToAnchor:(banner ? banner.bottomAnchor : self.headerView.bottomAnchor)
[stackContainer.topAnchor constraintEqualToAnchor:_scrollView.contentLayoutGuide.topAnchor constant:topOffset],
constant:16],
[stackContainer.bottomAnchor constraintEqualToAnchor:_scrollView.contentLayoutGuide.bottomAnchor],
[stack.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor],
[stack.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor],
// ⚡ Width locked to frame to prevent horizontal scroll
[stack.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor]
[stackContainer.widthAnchor constraintEqualToAnchor:_scrollView.frameLayoutGuide.widthAnchor],
// Leading/trailing optional, can just pin to zero if width is fixed
[stackContainer.leadingAnchor constraintEqualToAnchor:_scrollView.leadingAnchor],
[stackContainer.trailingAnchor constraintEqualToAnchor:_scrollView.trailingAnchor]
]];
]];
}
}
...
@@ -556,7 +591,7 @@
...
@@ -556,7 +591,7 @@
if (pill) {
if (pill) {
[constraints addObjectsFromArray:@[
[constraints addObjectsFromArray:@[
[pill.topAnchor constraintEqualToAnchor:titleLabel.bottomAnchor constant:
8
],
[pill.topAnchor constraintEqualToAnchor:titleLabel.bottomAnchor constant:
14
],
[pill.leadingAnchor constraintEqualToAnchor:banner.leadingAnchor constant:16],
[pill.leadingAnchor constraintEqualToAnchor:banner.leadingAnchor constant:16],
[pill.heightAnchor constraintEqualToConstant:28],
[pill.heightAnchor constraintEqualToConstant:28],
[pill.bottomAnchor constraintEqualToAnchor:banner.bottomAnchor constant:-16]
[pill.bottomAnchor constraintEqualToAnchor:banner.bottomAnchor constant:-16]
...
@@ -793,7 +828,7 @@
...
@@ -793,7 +828,7 @@
[hScroll.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:12],
[hScroll.topAnchor constraintEqualToAnchor:title.bottomAnchor constant:12],
[hScroll.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[hScroll.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[hScroll.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[hScroll.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[hScroll.heightAnchor constraintEqualToConstant:
9
0],
[hScroll.heightAnchor constraintEqualToConstant:
8
0],
[hScroll.bottomAnchor constraintEqualToAnchor:section.bottomAnchor] // important
[hScroll.bottomAnchor constraintEqualToAnchor:section.bottomAnchor] // important
]];
]];
...
@@ -942,7 +977,7 @@
...
@@ -942,7 +977,7 @@
[section addSubview:list];
[section addSubview:list];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor],
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor
constant:12
],
[list.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[list.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[list.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[list.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[list.bottomAnchor constraintEqualToAnchor:section.bottomAnchor]
[list.bottomAnchor constraintEqualToAnchor:section.bottomAnchor]
...
@@ -967,7 +1002,7 @@
...
@@ -967,7 +1002,7 @@
card.layer.shadowOpacity = 0.3;
card.layer.shadowOpacity = 0.3;
card.layer.shadowOffset = CGSizeMake(0, 1);
card.layer.shadowOffset = CGSizeMake(0, 1);
[card.heightAnchor constraintEqualToConstant:9
0
].active = YES;
[card.heightAnchor constraintEqualToConstant:9
2
].active = YES;
NSString *appointmentType = item[@"appointment_type"] ?: @"-";
NSString *appointmentType = item[@"appointment_type"] ?: @"-";
NSString *status = item[@"status"] ?: @"-";
NSString *status = item[@"status"] ?: @"-";
...
@@ -1015,8 +1050,8 @@
...
@@ -1015,8 +1050,8 @@
[card addSubview:desc];
[card addSubview:desc];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[iconCircle.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:1
2
],
[iconCircle.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:1
6
],
[iconCircle.topAnchor constraintEqualToAnchor:card.topAnchor constant:1
4
],
[iconCircle.topAnchor constraintEqualToAnchor:card.topAnchor constant:1
2
],
[iconCircle.widthAnchor constraintEqualToConstant:24],
[iconCircle.widthAnchor constraintEqualToConstant:24],
[iconCircle.heightAnchor constraintEqualToConstant:24],
[iconCircle.heightAnchor constraintEqualToConstant:24],
...
@@ -1026,15 +1061,15 @@
...
@@ -1026,15 +1061,15 @@
[bell.heightAnchor constraintEqualToConstant:16],
[bell.heightAnchor constraintEqualToConstant:16],
[statusLabel.leadingAnchor constraintEqualToAnchor:iconCircle.trailingAnchor constant:8],
[statusLabel.leadingAnchor constraintEqualToAnchor:iconCircle.trailingAnchor constant:8],
[statusLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:1
2
],
[statusLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:1
4
],
[timeLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[timeLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[timeLabel.centerYAnchor constraintEqualToAnchor:statusLabel.centerYAnchor],
[timeLabel.centerYAnchor constraintEqualToAnchor:statusLabel.centerYAnchor],
[desc.topAnchor constraintEqualToAnchor:
statusLabel.bottomAnchor constant:6
],
[desc.topAnchor constraintEqualToAnchor:
card.topAnchor constant:41
],
[desc.leadingAnchor constraintEqualToAnchor:
card.leadingAnchor constant:16
],
[desc.leadingAnchor constraintEqualToAnchor:
statusLabel.leadingAnchor
],
[desc.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-
16
],
[desc.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-
20
],
[desc.bottomAnchor constraintLessThanOrEqualToAnchor:card.bottomAnchor constant:-
8
]
[desc.bottomAnchor constraintLessThanOrEqualToAnchor:card.bottomAnchor constant:-
15
]
]];
]];
objc_setAssociatedObject(card, "appointmentData", item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(card, "appointmentData", item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
...
@@ -1107,7 +1142,7 @@
...
@@ -1107,7 +1142,7 @@
[section addSubview:list];
[section addSubview:list];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor],
[list.topAnchor constraintEqualToAnchor:title.bottomAnchor
constant:12
],
[list.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[list.leadingAnchor constraintEqualToAnchor:section.leadingAnchor],
[list.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[list.trailingAnchor constraintEqualToAnchor:section.trailingAnchor],
[list.bottomAnchor constraintEqualToAnchor:section.bottomAnchor]
[list.bottomAnchor constraintEqualToAnchor:section.bottomAnchor]
...
@@ -1130,7 +1165,7 @@
...
@@ -1130,7 +1165,7 @@
card.layer.shadowOpacity = 0.3;
card.layer.shadowOpacity = 0.3;
card.layer.shadowOffset = CGSizeMake(0, 1);
card.layer.shadowOffset = CGSizeMake(0, 1);
[card.heightAnchor constraintGreaterThanOrEqualToConstant:
110
].active = YES;
[card.heightAnchor constraintGreaterThanOrEqualToConstant:
92
].active = YES;
NSString *status = item[@"status_external"] ?: @"Unknown";
NSString *status = item[@"status_external"] ?: @"Unknown";
NSString *formattedDate = [self formatDate:item[@"created_at"]];
NSString *formattedDate = [self formatDate:item[@"created_at"]];
...
@@ -1157,7 +1192,7 @@
...
@@ -1157,7 +1192,7 @@
dateLabel.textAlignment = NSTextAlignmentRight;
dateLabel.textAlignment = NSTextAlignmentRight;
[card addSubview:dateLabel];
[card addSubview:dateLabel];
CGFloat imageSize =
44
;
CGFloat imageSize =
30
;
UIImageView *thumb = [[UIImageView alloc] init];
UIImageView *thumb = [[UIImageView alloc] init];
thumb.translatesAutoresizingMaskIntoConstraints = NO;
thumb.translatesAutoresizingMaskIntoConstraints = NO;
thumb.layer.cornerRadius = 6;
thumb.layer.cornerRadius = 6;
...
@@ -1195,12 +1230,12 @@
...
@@ -1195,12 +1230,12 @@
[card addSubview:info];
[card addSubview:info];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[dot.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:1
2
],
[dot.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:1
6
],
[dot.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[dot.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[dot.widthAnchor constraintEqualToConstant:16],
[dot.widthAnchor constraintEqualToConstant:16],
[dot.heightAnchor constraintEqualToConstant:16],
[dot.heightAnchor constraintEqualToConstant:16],
[statusLabel.leadingAnchor constraintEqualToAnchor:dot.trailingAnchor constant:
6
],
[statusLabel.leadingAnchor constraintEqualToAnchor:dot.trailingAnchor constant:
14
],
[statusLabel.centerYAnchor constraintEqualToAnchor:dot.centerYAnchor],
[statusLabel.centerYAnchor constraintEqualToAnchor:dot.centerYAnchor],
[dateLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[dateLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
...
@@ -1211,9 +1246,9 @@
...
@@ -1211,9 +1246,9 @@
[thumb.widthAnchor constraintEqualToConstant:imageSize],
[thumb.widthAnchor constraintEqualToConstant:imageSize],
[thumb.heightAnchor constraintEqualToConstant:imageSize],
[thumb.heightAnchor constraintEqualToConstant:imageSize],
[info.leadingAnchor constraintEqualToAnchor:thumb.trailingAnchor constant:1
0
],
[info.leadingAnchor constraintEqualToAnchor:thumb.trailingAnchor constant:1
4
],
[info.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-1
2
],
[info.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-1
4
],
[info.
centerYAnchor constraintEqualToAnchor:thumb.centerYAnchor
],
[info.
topAnchor constraintEqualToAnchor:card.topAnchor constant:41
],
[info.bottomAnchor constraintLessThanOrEqualToAnchor:card.bottomAnchor constant:-10]
[info.bottomAnchor constraintLessThanOrEqualToAnchor:card.bottomAnchor constant:-10]
]];
]];
...
@@ -1493,4 +1528,21 @@
...
@@ -1493,4 +1528,21 @@
[self.navigationController popViewControllerAnimated:YES];
[self.navigationController popViewControllerAnimated:YES];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offsetY = scrollView.contentOffset.y;
// Parallax effect for the header image
if (offsetY < 0) {
self.backgroundImageView.transform = CGAffineTransformMakeTranslation(0, offsetY / 2);
} else {
self.backgroundImageView.transform = CGAffineTransformIdentity;
}
// Gradually fade in sticky bar
CGFloat fadeStart = 0;
CGFloat fadeEnd = 100; // how far scroll before fully opaque
CGFloat alpha = MIN(MAX((offsetY - fadeStart) / (fadeEnd - fadeStart), 0), 1);
self.stickyBar.backgroundColor = [UIColor colorWithRed:0 green:0.43 blue:0.55 alpha:alpha];
}
@end
@end
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/GeneralInfoViewController.mm
View file @
3995f152
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
@property (nonatomic) NSLayoutConstraint *infoBottom;
@property (nonatomic) NSLayoutConstraint *infoBottom;
@property (nonatomic) NSLayoutConstraint *documentsBottom;
@property (nonatomic) NSLayoutConstraint *documentsBottom;
@property (nonatomic) NSLayoutConstraint *formsBottom;
@property (nonatomic) NSLayoutConstraint *formsBottom;
@property (nonatomic, strong) UILabel *jointTitleLabel;
// Sections for tabs
// Sections for tabs
@property (nonatomic, strong) UIView *infoContainer;
@property (nonatomic, strong) UIView *infoContainer;
...
@@ -238,12 +239,12 @@ typedef struct {
...
@@ -238,12 +239,12 @@ typedef struct {
[self.infoContainer addSubview:self.ownerStack];
[self.infoContainer addSubview:self.ownerStack];
// --- Joint Owners Title ---
// --- Joint Owners Title ---
UILabel *jointTitle
= [[UILabel alloc] init];
self.jointTitleLabel
= [[UILabel alloc] init];
jointTitle
.text = @"Joint Owner Details";
self.jointTitleLabel
.text = @"Joint Owner Details";
jointTitle
.font = [UIFont boldSystemFontOfSize:16];
self.jointTitleLabel
.font = [UIFont boldSystemFontOfSize:16];
jointTitle
.textColor = UIColor.darkGrayColor;
self.jointTitleLabel
.textColor = UIColor.darkGrayColor;
jointTitle
.translatesAutoresizingMaskIntoConstraints = NO;
self.jointTitleLabel
.translatesAutoresizingMaskIntoConstraints = NO;
[self.infoContainer addSubview:
jointTitle
];
[self.infoContainer addSubview:
self.jointTitleLabel
];
// --- Joint Owners Stack ---
// --- Joint Owners Stack ---
self.jointOwnersStack = [[UIStackView alloc] init];
self.jointOwnersStack = [[UIStackView alloc] init];
...
@@ -276,10 +277,10 @@ typedef struct {
...
@@ -276,10 +277,10 @@ typedef struct {
[self.ownerStack.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.ownerStack.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.ownerStack.trailingAnchor constraintEqualToAnchor:self.infoContainer.trailingAnchor constant:-16],
[self.ownerStack.trailingAnchor constraintEqualToAnchor:self.infoContainer.trailingAnchor constant:-16],
[
jointTitle
.topAnchor constraintEqualToAnchor:self.ownerStack.bottomAnchor constant:20],
[
self.jointTitleLabel
.topAnchor constraintEqualToAnchor:self.ownerStack.bottomAnchor constant:20],
[
jointTitle
.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[
self.jointTitleLabel
.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.jointOwnersStack.topAnchor constraintEqualToAnchor:
jointTitle
.bottomAnchor constant:12],
[self.jointOwnersStack.topAnchor constraintEqualToAnchor:
self.jointTitleLabel
.bottomAnchor constant:12],
[self.jointOwnersStack.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.jointOwnersStack.leadingAnchor constraintEqualToAnchor:self.infoContainer.leadingAnchor constant:16],
[self.jointOwnersStack.trailingAnchor constraintEqualToAnchor:self.infoContainer.trailingAnchor constant:-16],
[self.jointOwnersStack.trailingAnchor constraintEqualToAnchor:self.infoContainer.trailingAnchor constant:-16],
...
@@ -643,7 +644,6 @@ typedef struct {
...
@@ -643,7 +644,6 @@ typedef struct {
}
}
maxTitleWidth += 6;
maxTitleWidth += 6;
UIStackView* (^OwnerCard)(NSDictionary *) = ^UIStackView* (NSDictionary *owner) {
UIStackView* (^OwnerCard)(NSDictionary *) = ^UIStackView* (NSDictionary *owner) {
UIStackView *card = [[UIStackView alloc] init];
UIStackView *card = [[UIStackView alloc] init];
...
@@ -698,6 +698,11 @@ typedef struct {
...
@@ -698,6 +698,11 @@ typedef struct {
for (NSDictionary *owner in self.jointOwners) {
for (NSDictionary *owner in self.jointOwners) {
[self.jointOwnersStack addArrangedSubview:OwnerCard(owner)];
[self.jointOwnersStack addArrangedSubview:OwnerCard(owner)];
}
}
BOOL hasJointOwners = self.jointOwnersStack.arrangedSubviews.count > 0;
self.jointOwnersStack.hidden = !hasJointOwners;
self.jointTitleLabel.hidden = !hasJointOwners;
// ------------------------
// ------------------------
// 2️⃣ UNIT INFO SECTION
// 2️⃣ UNIT INFO SECTION
...
...
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/ProjectViewController.mm
View file @
3995f152
...
@@ -34,10 +34,10 @@
...
@@ -34,10 +34,10 @@
// label
// label
self.nameLabel = [[UILabel alloc] init];
self.nameLabel = [[UILabel alloc] init];
self.nameLabel.font = [UIFont boldSystemFontOfSize:
20
];
self.nameLabel.font = [UIFont boldSystemFontOfSize:
18
];
self.nameLabel.textColor = UIColor.whiteColor;
self.nameLabel.textColor = UIColor.whiteColor;
self.nameLabel.backgroundColor =
//
self.nameLabel.backgroundColor =
[[UIColor blackColor] colorWithAlphaComponent:0.35];
//
[[UIColor blackColor] colorWithAlphaComponent:0.35];
self.nameLabel.numberOfLines = 2;
self.nameLabel.numberOfLines = 2;
self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:self.nameLabel];
[self.contentView addSubview:self.nameLabel];
...
@@ -116,24 +116,24 @@
...
@@ -116,24 +116,24 @@
NSLog(@"ClientCode: %@", self.ClientCode);
NSLog(@"ClientCode: %@", self.ClientCode);
NSLog(@"user_token: %@", self.user_token);
NSLog(@"user_token: %@", self.user_token);
[self showLoadingOverlay:@"Loading..."];
//
[self showLoadingOverlay:@"Loading..."];
//
if (![self isReadyToLoadDashboard]) {
//
if (![self isReadyToLoadDashboard]) {
NSLog(@"⏳ Waiting for all credentials to be ready...");
//
NSLog(@"⏳ Waiting for all credentials to be ready...");
return;
//
return;
}
//
}
//
if (_isLoadingDashboard) return;
//
if (_isLoadingDashboard) return;
//
self.isLoadingDashboard = YES;
//
self.isLoadingDashboard = YES;
//
NSLog(@"✅ All credentials ready. ClientID: %@, ClientCode: %@, user_token: %@",
//
NSLog(@"✅ All credentials ready. ClientID: %@, ClientCode: %@, user_token: %@",
self.ClientID, self.ClientCode, self.user_token);
//
self.ClientID, self.ClientCode, self.user_token);
//
//
[APIConfig setAuthTokem:self.user_token];
//
[APIConfig setAuthTokem:self.user_token];
[APIConfig setClientId:self.ClientID];
//
[APIConfig setClientId:self.ClientID];
[self requestProjectList]
;
self.ClientCode = @"spt"
;
[self requestCompanyCode];
[self requestCompanyCode];
}
}
...
@@ -185,7 +185,7 @@
...
@@ -185,7 +185,7 @@
- (void)setupCollectionView {
- (void)setupCollectionView {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.minimumLineSpacing = 1
6
;
layout.minimumLineSpacing = 1
2
;
layout.minimumInteritemSpacing = 16;
layout.minimumInteritemSpacing = 16;
layout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
layout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
...
@@ -202,7 +202,7 @@
...
@@ -202,7 +202,7 @@
// constraints
// constraints
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[self.collectionView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:
8
],
[self.collectionView.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:
20
],
[self.collectionView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.collectionView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.collectionView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.collectionView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
[self.collectionView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
...
@@ -273,7 +273,7 @@
...
@@ -273,7 +273,7 @@
CGFloat horizontalInset = 16 * 2; // section inset left + right
CGFloat horizontalInset = 16 * 2; // section inset left + right
CGFloat width = collectionView.bounds.size.width - horizontalInset;
CGFloat width = collectionView.bounds.size.width - horizontalInset;
CGFloat height =
20
0; // OG-style banner height
CGFloat height =
14
0; // OG-style banner height
return CGSizeMake(width, height);
return CGSizeMake(width, height);
}
}
...
@@ -399,16 +399,12 @@
...
@@ -399,16 +399,12 @@
NSLog(@"❌ API failure: %@", appData[@"message"]);
NSLog(@"❌ API failure: %@", appData[@"message"]);
return;
return;
}
}
NSArray *project = data[@"Data"];
if (![project isKindOfClass:[NSArray class]]) {
NSLog(@"❌ Invalid project list format");
return;
}
if (!error) {
if (!error) {
NSString *rawURL = data[@"Data"][@"url_path"];
NSString *rawURL = data[@"Data"][@"url_path"];
NSString *baseURL = rawURL;
NSString *baseURL = rawURL;
NSLog(@"base url: %@", baseURL);
// remove trailing slash if exists
// remove trailing slash if exists
if ([baseURL hasSuffix:@"/"]) {
if ([baseURL hasSuffix:@"/"]) {
...
@@ -418,7 +414,8 @@
...
@@ -418,7 +414,8 @@
// append /api
// append /api
baseURL = [baseURL stringByAppendingString:@"/api"];
baseURL = [baseURL stringByAppendingString:@"/api"];
NSLog(@"baseURL: %@", baseURL);
NSLog(@"baseURL: %@", baseURL);
// [APIConfig setBaseURL:baseURL];
[APIConfig setBaseURL:baseURL];
[self requestProjectList];
}
}
}];
}];
}
}
...
...
framework/QmsPluginFramework/QmsPluginFramework/Dashboard/UnitViewController.mm
View file @
3995f152
...
@@ -110,10 +110,10 @@
...
@@ -110,10 +110,10 @@
[self.view addSubview:self.searchBar];
[self.view addSubview:self.searchBar];
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[self.searchBar.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:
8
],
[self.searchBar.topAnchor constraintEqualToAnchor:self.headerView.bottomAnchor constant:
0
],
[self.searchBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.searchBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:16],
[self.searchBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.searchBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16],
[self.searchBar.heightAnchor constraintEqualToConstant:
44
]
[self.searchBar.heightAnchor constraintEqualToConstant:
72
]
]];
]];
}
}
...
@@ -150,12 +150,20 @@
...
@@ -150,12 +150,20 @@
forCellReuseIdentifier:@"UnitCell"];
forCellReuseIdentifier:@"UnitCell"];
[self.view addSubview:self.tableView];
[self.view addSubview:self.tableView];
UILabel *footerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 50)];
footerLabel.text = @"All items displayed";
footerLabel.textColor = UIColor.systemGrayColor;
footerLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
footerLabel.textAlignment = NSTextAlignmentCenter;
self.tableView.tableFooterView = footerLabel;
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
[self.tableView.topAnchor constraintEqualToAnchor:self.searchBar.bottomAnchor constant:
8
],
[self.tableView.topAnchor constraintEqualToAnchor:self.searchBar.bottomAnchor constant:
12
],
[self.tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.tableView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor
constant:16
],
[self.tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.tableView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor
constant:-16
],
[self.tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]
[self.tableView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor
constant:self.view.safeAreaInsets.bottom
]
]];
]];
}
}
...
@@ -169,6 +177,7 @@
...
@@ -169,6 +177,7 @@
UITableViewCell *cell =
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:@"UnitCell"
[tableView dequeueReusableCellWithIdentifier:@"UnitCell"
forIndexPath:indexPath];
forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// ---- Reset reused cell ----
// ---- Reset reused cell ----
for (UIView *subview in cell.contentView.subviews) {
for (UIView *subview in cell.contentView.subviews) {
...
@@ -186,25 +195,30 @@
...
@@ -186,25 +195,30 @@
// ---- Arrow ----
// ---- Arrow ----
UIImageView *arrow = [[UIImageView alloc] initWithImage:
UIImageView *arrow = [[UIImageView alloc] initWithImage:
[UIImage systemImageNamed:@"chevron.right"]];
[UIImage systemImageNamed:@"chevron.right"]];
arrow.tintColor =
UIColor.systemGrayColor
;
arrow.tintColor =
[UIColor colorWithRed:0.0 green:0.5 blue:0.6 alpha:1.0]
;
arrow.translatesAutoresizingMaskIntoConstraints = NO;
arrow.translatesAutoresizingMaskIntoConstraints = NO;
// ---- Card styling ----
// ---- Card styling ----
cell.backgroundColor = UIColor.clearColor;
UIView *cardView = [[UIView alloc] init];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cardView.backgroundColor = UIColor.whiteColor;
cardView.layer.cornerRadius = 12;
cell.contentView.backgroundColor = UIColor.whiteColor;
cardView.layer.borderWidth = 1;
cell.contentView.layer.cornerRadius = 12;
cardView.layer.borderColor = UIColor.systemGray4Color.CGColor;
cell.contentView.layer.borderWidth = 1;
cardView.translatesAutoresizingMaskIntoConstraints = NO;
cell.contentView.layer.borderColor = UIColor.systemGray4Color.CGColor;
[cell.contentView addSubview:cardView];
cell.contentView.clipsToBounds = YES;
// Put label & arrow inside cardView
// ---- Add views ----
[cardView addSubview:label];
[cell.contentView addSubview:label];
[cardView addSubview:arrow];
[cell.contentView addSubview:arrow];
// ---- Constraints ----
// ---- Constraints ----
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint activateConstraints:@[
// Cardview
[cardView.topAnchor constraintEqualToAnchor:cell.contentView.topAnchor constant:8], // vertical spacing top
[cardView.bottomAnchor constraintEqualToAnchor:cell.contentView.bottomAnchor constant:-8], // vertical spacing bottom
[cardView.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:0], // horizontal spacing
[cardView.trailingAnchor constraintEqualToAnchor:cell.contentView.trailingAnchor constant:0],
// Label
// Label
[label.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:16],
[label.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:16],
[label.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor],
[label.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor],
...
@@ -230,7 +244,7 @@ forRowAtIndexPath:(NSIndexPath *)indexPath {
...
@@ -230,7 +244,7 @@ forRowAtIndexPath:(NSIndexPath *)indexPath {
- (CGFloat)tableView:(UITableView *)tableView
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 6
4
;
return 6
6
;
}
}
- (void)tableView:(UITableView *)tableView
- (void)tableView:(UITableView *)tableView
...
...
framework/QmsPluginFramework/QmsPluginFramework/Issue/HistoryViewController.mm
View file @
3995f152
...
@@ -60,8 +60,7 @@
...
@@ -60,8 +60,7 @@
#pragma mark - Header
#pragma mark - Header
- (void)setupHeader {
- (void)setupHeader {
CGFloat statusBarHeight = UIApplication.sharedApplication.statusBarFrame.size.height;
self.headerView = [[UIView alloc] init];
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, statusBarHeight + 60)];
self.headerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
self.headerView.backgroundColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView];
[self.view addSubview:self.headerView];
...
...
framework/QmsPluginFramework/QmsPluginFramework/Issue/IssuesViewController.mm
View file @
3995f152
...
@@ -82,30 +82,31 @@
...
@@ -82,30 +82,31 @@
[card.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:6],
[card.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:6],
[card.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:10],
[card.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:10],
[card.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-10],
[card.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:-10],
[card.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-6],
[card.heightAnchor constraintEqualToConstant:141],
[self.thumbView.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[self.thumbView.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[self.thumbView.widthAnchor constraintEqualToConstant:44],
[self.thumbView.heightAnchor constraintEqualToConstant:44],
[self.statusLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[self.statusLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[self.statusLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[self.statusLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:12],
[self.statusLabel.widthAnchor constraintEqualToConstant:70],
[self.statusLabel.widthAnchor constraintEqualToConstant:70],
[self.statusLabel.heightAnchor constraintEqualToConstant:24],
[self.statusLabel.heightAnchor constraintEqualToConstant:24],
[self.referenceLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[self.referenceLabel.trailingAnchor constraintEqualToAnchor:self.statusLabel.leadingAnchor constant:16],
[self.referenceLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:16],
[self.thumbView.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:16],
[self.thumbView.topAnchor constraintEqualToAnchor:self.referenceLabel.bottomAnchor constant:12],
[self.thumbView.widthAnchor constraintEqualToConstant:44],
[self.thumbView.heightAnchor constraintEqualToConstant:44],
[self.locationLabel.leadingAnchor constraintEqualToAnchor:self.thumbView.trailingAnchor constant:12],
[self.locationLabel.leadingAnchor constraintEqualToAnchor:self.thumbView.trailingAnchor constant:12],
[self.locationLabel.
topAnchor constraintEqualToAnchor:card.topAnchor constant:12
],
[self.locationLabel.
bottomAnchor constraintEqualToAnchor:self.thumbView.centerYAnchor constant:-1
],
[self.createdLabel.leadingAnchor constraintEqualToAnchor:self.thumbView.trailingAnchor constant:12],
[self.createdLabel.leadingAnchor constraintEqualToAnchor:self.thumbView.trailingAnchor constant:12],
[self.createdLabel.topAnchor constraintEqualToAnchor:self.locationLabel.bottomAnchor constant:4],
[self.createdLabel.topAnchor constraintEqualToAnchor:self.thumbView.centerYAnchor constant:1],
[self.referenceLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[self.referenceLabel.topAnchor constraintEqualToAnchor:self.thumbView.bottomAnchor constant:8],
[self.detailsLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[self.detailsLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:12],
[self.detailsLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[self.detailsLabel.trailingAnchor constraintEqualToAnchor:card.trailingAnchor constant:-12],
[self.detailsLabel.topAnchor constraintEqualToAnchor:self.
referenceLabel.bottomAnchor constant:4
],
[self.detailsLabel.topAnchor constraintEqualToAnchor:self.
thumbView.bottomAnchor constant:12
],
[self.detailsLabel.bottomAnchor constraintEqualToAnchor:card.bottomAnchor constant:-12],
[self.detailsLabel.bottomAnchor constraintEqualToAnchor:card.bottomAnchor constant:-12],
]];
]];
}
}
...
...
framework/QmsPluginFramework/QmsPluginFramework/Sync/SyncProjectViewController.mm
View file @
3995f152
...
@@ -715,8 +715,6 @@ didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
...
@@ -715,8 +715,6 @@ didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
for (SyncUnit *unit in self.selectedUnits) {
for (SyncUnit *unit in self.selectedUnits) {
[dictArray addObject:[self dictionaryFromUnit:unit]];
[dictArray addObject:[self dictionaryFromUnit:unit]];
}
}
[LocalStorage saveArray:dictArray forKey:@"SELECTED_OFFLINE_UNITS"];
[self showOfflineUnit];
[self showOfflineUnit];
}
}
...
...
framework/QmsPluginFramework/QmsPluginFramework/Sync/SyncScreenViewController.mm
View file @
3995f152
...
@@ -670,7 +670,7 @@ static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";
...
@@ -670,7 +670,7 @@ static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";
}
}
- (NSInteger)loadOfflineUnitCount {
- (NSInteger)loadOfflineUnitCount {
NSArray *units = [LocalStorage loadArrayForKey:
@"SELECTED_OFFLINE_UNITS"
];
NSArray *units = [LocalStorage loadArrayForKey:
kSyncSelectedUnitsKey
];
return units.count;
return units.count;
}
}
...
@@ -714,5 +714,4 @@ static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";
...
@@ -714,5 +714,4 @@ static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";
self.yesBtn.alpha = enabled ? 1.0 : 0.5;
self.yesBtn.alpha = enabled ? 1.0 : 0.5;
}
}
@end
@end
framework/QmsPluginFramework/QmsPluginFramework/Utilities/API/APIClient.mm
View file @
3995f152
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
return;
return;
}
}
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getAccessItem"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/plan/getAccessItem"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -84,7 +84,7 @@
...
@@ -84,7 +84,7 @@
}
}
// ✅ Construct URL (with token)
// ✅ Construct URL (with token)
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getLocationByUnit"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/plan/getLocationByUnit"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -177,7 +177,7 @@
...
@@ -177,7 +177,7 @@
return;
return;
}
}
NSURL *url = [APIConfig urlWithPath:@"/issue/getGeneralSettingByLocation"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
issue/getGeneralSettingByLocation"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -269,7 +269,7 @@
...
@@ -269,7 +269,7 @@
images:(NSArray<UIImage *> * _Nullable)images
images:(NSArray<UIImage *> * _Nullable)images
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/addIssue"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/addIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -361,7 +361,7 @@
...
@@ -361,7 +361,7 @@
images:(NSArray<UIImage *> * _Nullable)images
images:(NSArray<UIImage *> * _Nullable)images
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion{
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion{
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/updateIssue"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/updateIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -470,7 +470,7 @@
...
@@ -470,7 +470,7 @@
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/getSlot"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/appointment/getSlot"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -544,7 +544,7 @@
...
@@ -544,7 +544,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getUnitInfo"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/plan/getUnitInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -614,7 +614,7 @@
...
@@ -614,7 +614,7 @@
+ (void)submitAppointment:(NSDictionary *)appointmentData
+ (void)submitAppointment:(NSDictionary *)appointmentData
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/makeAppointment"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/appointment/makeAppointment"];
NSLog(@"🌍 SUBMIT (NO REP) URL: %@", url.absoluteString);
NSLog(@"🌍 SUBMIT (NO REP) URL: %@", url.absoluteString);
NSLog(@"📦 SUBMIT (NO REP) Body JSON: %@", appointmentData);
NSLog(@"📦 SUBMIT (NO REP) Body JSON: %@", appointmentData);
...
@@ -673,7 +673,7 @@
...
@@ -673,7 +673,7 @@
+ (void)submitRepresentativeAppointment:(NSDictionary *)repData
+ (void)submitRepresentativeAppointment:(NSDictionary *)repData
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/makeAppointment"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/appointment/makeAppointment"];
NSLog(@"🌍 SUBMIT URL: %@", url.absoluteString);
NSLog(@"🌍 SUBMIT URL: %@", url.absoluteString);
// Create request
// Create request
...
@@ -743,7 +743,7 @@
...
@@ -743,7 +743,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/appointment/cancelAppointment"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/appointment/cancelAppointment"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -817,7 +817,7 @@
...
@@ -817,7 +817,7 @@
return;
return;
}
}
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getIssueUpdateAppointmentInfo"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/plan/getIssueUpdateAppointmentInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -883,7 +883,7 @@
...
@@ -883,7 +883,7 @@
return;
return;
}
}
// ✅ Keep token in URL
// ✅ Keep token in URL
NSURL *url = [APIConfig urlWithPath:@"/clientAnnouncement"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
clientAnnouncement"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -960,7 +960,7 @@
...
@@ -960,7 +960,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/getIssueHistory"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/getIssueHistory"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1033,7 +1033,7 @@
...
@@ -1033,7 +1033,7 @@
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/addInfo"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/addInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1103,7 +1103,7 @@
...
@@ -1103,7 +1103,7 @@
mediaType:(NSString *)mediaType
mediaType:(NSString *)mediaType
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/addInfo"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/addInfo"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1218,7 +1218,7 @@
...
@@ -1218,7 +1218,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/getIssue"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/getIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1294,7 +1294,7 @@
...
@@ -1294,7 +1294,7 @@
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/voidIssue"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/voidIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1377,7 +1377,7 @@
...
@@ -1377,7 +1377,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/deleteIssue"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/deleteIssue"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1451,7 +1451,7 @@
...
@@ -1451,7 +1451,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/plan/getCommonArea"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/plan/getCommonArea"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1525,7 +1525,7 @@
...
@@ -1525,7 +1525,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/issue/getGeneralSetting"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/issue/getGeneralSetting"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1599,7 +1599,7 @@
...
@@ -1599,7 +1599,7 @@
// return;
// return;
// }
// }
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/issue/getGeneralSettingByUnit"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
issue/getGeneralSettingByUnit"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1669,7 +1669,7 @@
...
@@ -1669,7 +1669,7 @@
return;
return;
}
}
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/project/listProject"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/project/listProject"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
@@ -1739,7 +1739,7 @@
...
@@ -1739,7 +1739,7 @@
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion {
// ✅ URL
// ✅ URL
NSURL *url = [APIConfig urlWithPath:@"/owner/offline/syncImageArray"];
NSURL *url = [APIConfig urlWithPath:@"/
framework/
owner/offline/syncImageArray"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPMethod = @"POST";
...
...
framework/QmsPluginFramework/QmsPluginFramework/Utilities/API/APIConfig.mm
View file @
3995f152
...
@@ -3,10 +3,10 @@
...
@@ -3,10 +3,10 @@
#import "LocalStorage.h"
#import "LocalStorage.h"
#import "NetworkManager.h"
#import "NetworkManager.h"
static NSString *kBaseURL = @"https://
kitadev
.commudesk.com/api";
static NSString *kBaseURL = @"https://
sptest
.commudesk.com/api";
static NSString *kDrawingPlanId = @"";
static NSString *kDrawingPlanId = @"";
static NSString *kProjectId = @"";
static NSString *kProjectId = @"";
static NSString *kAuthToken = @"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ
lbWFpbCI6ImF0aGlyYWh6YWlkaUBjb252ZXAuY29tIiwicGFzc3dvcmQiOiIkMnkkMTAkNU9xYklqMnZ6UHJwckJrcVd5c3I2LmJCc1hVYS9Hd014eUhnL3RhUUhPUkNQcGdmTG8yakciLCJzdWIiOjIxNzAsImlzcyI6Imh0dHBzOi8va2l0YWRldi5jb21tdWRlc2suY29tL2FwaS9vd25lci9hdXRoL3Bhc3N3b3JkbGVzc19sb2dpbiIsImlhdCI6MTc2MDMxNTM1MiwiZXhwIjoyMDc1ODg0ODcyLCJuYmYiOjE3NjAzMTUzNTIsImp0aSI6IktoQmNyQnJEdDVNdDZlWmMifQ.JnxGbZ7hTeoOr6oibIzZMphgyKtTo2Aq9Efx6mrGfFA
";
static NSString *kAuthToken = @"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ
zY29wZSI6InNlcnZlci10by1zZXJ2ZXIiLCJmcmFtZXdvcmstYXBpIjp0cnVlLCJjb21wYW55X2NvZGUiOiJTUFQiLCJzdWIiOjE1NTcsImlzcyI6Imh0dHBzOi8vc3B0ZXN0LmNvbW11ZGVzay5jb20vYXBpL2ZyYW1ld29yay9vd25lci9hdXRoL2NsaWVudF9hdXRoZW50aWNhdGlvbiIsImlhdCI6MTc2Nzc1MjU5OSwiZXhwIjoyMDgzMzIyMTE5LCJuYmYiOjE3Njc3NTI1OTksImp0aSI6IktEcmhmSXgzeWU0WmxaUEYifQ.Bv4ZSjGRm9YYOjGItLSV_3wS7grKuPTabL60BFnp88o
";
static NSString *kClientId = @"3";
static NSString *kClientId = @"3";
@implementation APIConfig
@implementation APIConfig
...
...
ios/QmsPlugin/QmsDashboardViewManager.mm
View file @
3995f152
...
@@ -6,43 +6,75 @@
...
@@ -6,43 +6,75 @@
@interface QmsDashboardView : UIView
@interface QmsDashboardView : UIView
@property (nonatomic, strong) UIViewController *dashboardVC;
@property (nonatomic, strong) UIViewController *dashboardVC;
@property (nonatomic, assign) BOOL didSetupVC;
@property (nonatomic, assign) BOOL didSetupVC;
// New props
@property (nonatomic, copy) NSString *ClientID;
@property (nonatomic, copy) NSString *ClientID;
@property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *ClientCode;
@property (nonatomic, copy) NSString *user_token;
@property (nonatomic, copy) NSString *user_token;
@property (nonatomic, copy) RCTDirectEventBlock onClose;
@end
@end
@implementation QmsDashboardView
@implementation QmsDashboardView
- (instancetype)initWithFrame:(CGRect)frame {
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
if (self = [super initWithFrame:frame]) {
_dashboardVC = [QmsPluginUI makeViewController];
_dashboardVC = [QmsPluginUI makeViewController];
_didSetupVC = NO;
_didSetupVC = NO;
_dashboardVC.view.backgroundColor = [UIColor whiteColor];
_dashboardVC.view.backgroundColor = [UIColor whiteColor];
// Listen for native dashboard close notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleDashboardClose:)
name:@"QmsDashboardDidCloseNotification"
object:nil];
}
}
return self;
return self;
}
}
- (void)didMoveToWindow {
- (void)didMoveToWindow {
[super didMoveToWindow];
[super didMoveToWindow];
if (self.window && !_didSetupVC) {
if (self.window && !_didSetupVC) {
UIViewController *parentVC = [UIApplication sharedApplication].keyWindow.rootViewController;
UIViewController *parentVC = [UIApplication sharedApplication].keyWindow.rootViewController;
if (parentVC) {
if (parentVC) {
[parentVC addChildViewController:_dashboardVC];
_dashboardVC.view.frame = parentVC.view.bounds;
// 1️⃣ create VC with props
_dashboardVC.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_dashboardVC = [QmsPluginUI makeViewController];
[parentVC.view addSubview:_dashboardVC.view];
[_dashboardVC didMoveToParentViewController:parentVC];
[parentVC addChildViewController:_dashboardVC];
_didSetupVC = YES;
_dashboardVC.view.frame = parentVC.view.bounds;
_dashboardVC.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// Forward props once the VC is added
[parentVC.view addSubview:_dashboardVC.view];
[self forwardPropsToVC];
[_dashboardVC didMoveToParentViewController:parentVC];
_didSetupVC = YES;
// 2️⃣ forward props again if needed
[self forwardPropsToVC];
}
}
}
}
}
}
#pragma mark - Prop Setters
- (void)handleDashboardClose:(NSNotification *)note {
// 1️⃣ Notify JS
if (self.onClose) {
self.onClose(@{});
}
// 2️⃣ Clean up the native view controller
[self cleanupDashboard];
}
- (void)cleanupDashboard {
if (!_dashboardVC) return;
[_dashboardVC willMoveToParentViewController:nil];
[_dashboardVC.view removeFromSuperview];
[_dashboardVC removeFromParentViewController];
_dashboardVC = nil;
_didSetupVC = NO;
}
#pragma mark - Prop Setters
- (void)setClientID:(NSString *)ClientID {
- (void)setClientID:(NSString *)ClientID {
_ClientID = [ClientID copy];
_ClientID = [ClientID copy];
[self forwardProp:@"ClientID" value:_ClientID];
[self forwardProp:@"ClientID" value:_ClientID];
...
@@ -59,7 +91,6 @@
...
@@ -59,7 +91,6 @@
}
}
#pragma mark - Forward Props via KVC
#pragma mark - Forward Props via KVC
- (void)forwardProp:(NSString *)key value:(NSString *)value {
- (void)forwardProp:(NSString *)key value:(NSString *)value {
if (_dashboardVC && [_dashboardVC respondsToSelector:NSSelectorFromString(key)]) {
if (_dashboardVC && [_dashboardVC respondsToSelector:NSSelectorFromString(key)]) {
@try {
@try {
...
@@ -76,6 +107,11 @@
...
@@ -76,6 +107,11 @@
[self forwardProp:@"user_token" value:_user_token];
[self forwardProp:@"user_token" value:_user_token];
}
}
- (void)removeFromSuperview {
[self cleanupDashboard];
[super removeFromSuperview];
}
@end
@end
@interface QmsDashboardViewManager : RCTViewManager
@interface QmsDashboardViewManager : RCTViewManager
...
...
ios/QmsPluginFramework.xcframework/Info.plist
View file @
3995f152
...
@@ -8,32 +8,32 @@
...
@@ -8,32 +8,32 @@
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
string
>
ios-arm64
_x86_64-simulator
<
/string
>
<
string
>
ios-arm64
<
/string
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
a
rr
a
y
>
<
a
rr
a
y
>
<
string
>
arm64
<
/string
>
<
string
>
arm64
<
/string
>
<
string
>
x86_64
<
/string
>
<
/
a
rr
a
y
>
<
/
a
rr
a
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
string
>
ios
<
/string
>
<
string
>
ios
<
/string
>
<
k
e
y
>
SupportedPlatformVariant
<
/k
e
y
>
<
string
>
simulator
<
/string
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
k
e
y
>
BinaryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
string
>
QmsPluginFramework.framework/QmsPluginFramework
<
/string
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
k
e
y
>
LibraryIdentifier
<
/k
e
y
>
<
string
>
ios-arm64
<
/string
>
<
string
>
ios-arm64
_x86_64-simulator
<
/string
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
k
e
y
>
LibraryPath
<
/k
e
y
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
string
>
QmsPluginFramework.framework
<
/string
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
k
e
y
>
SupportedArchitectures
<
/k
e
y
>
<
a
rr
a
y
>
<
a
rr
a
y
>
<
string
>
arm64
<
/string
>
<
string
>
arm64
<
/string
>
<
string
>
x86_64
<
/string
>
<
/
a
rr
a
y
>
<
/
a
rr
a
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
k
e
y
>
SupportedPlatform
<
/k
e
y
>
<
string
>
ios
<
/string
>
<
string
>
ios
<
/string
>
<
k
e
y
>
SupportedPlatformVariant
<
/k
e
y
>
<
string
>
simulator
<
/string
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
/
a
rr
a
y
>
<
/
a
rr
a
y
>
<
k
e
y
>
CFBundlePackageType
<
/k
e
y
>
<
k
e
y
>
CFBundlePackageType
<
/k
e
y
>
...
...
ios/QmsPluginFramework.xcframework/ios-arm64/QmsPluginFramework.framework/QmsPluginFramework
View file @
3995f152
No preview for this file type
ios/QmsPluginFramework.xcframework/ios-arm64_x86_64-simulator/QmsPluginFramework.framework/QmsPluginFramework
View file @
3995f152
No preview for this file type
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment