Commit 6da6b554 authored by Wei Han's avatar Wei Han

code update

parent 9e06acac
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string> <string>ios-arm64</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64</string> <string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
</array> </array>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
......
...@@ -512,7 +512,7 @@ ...@@ -512,7 +512,7 @@
return; return;
} }
[APIClient fetchCancelAppointment:self.appointmentData[@"appointment_id"] [APIClient requestCancelAppointment:self.appointmentData[@"appointment_id"]
reason:remarks reason:remarks
completion:^(NSDictionary *data, NSError *error) completion:^(NSDictionary *data, NSError *error)
{ {
......
...@@ -285,7 +285,7 @@ ...@@ -285,7 +285,7 @@
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
[self fetchAccessItem]; [self requestAccessItem];
self.view.backgroundColor = UIColor.whiteColor; self.view.backgroundColor = UIColor.whiteColor;
[self setupHeader]; [self setupHeader];
...@@ -361,7 +361,7 @@ ...@@ -361,7 +361,7 @@
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;
[self.tableView addPullToRefresh:^(UIRefreshControl *refresh) { [self.tableView addPullToRefresh:^(UIRefreshControl *refresh) {
[weakSelf fetchAccessItem]; [weakSelf requestAccessItem];
}]; }];
[self.view addSubview:self.tableView]; [self.view addSubview:self.tableView];
...@@ -375,8 +375,8 @@ ...@@ -375,8 +375,8 @@
} }
#pragma mark - Api #pragma mark - Api
- (void)fetchAccessItem{ - (void)requestAccessItem{
[APIClient fetchAccessItem:@"135" [APIClient requestAccessItem:@"135"
completion:^(BOOL success, NSDictionary *data, NSError *error) { completion:^(BOOL success, NSDictionary *data, NSError *error) {
NSLog(@"📦 Received General Info Data: %@", data); NSLog(@"📦 Received General Info Data: %@", data);
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
[super viewDidLoad]; [super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor; self.view.backgroundColor = UIColor.whiteColor;
[self fetchGeneralInfo]; [self requestGeneralInfo];
[self setupNavBar]; [self setupNavBar];
[self setupUnitInfoHeader]; [self setupUnitInfoHeader];
[self setupTabsBar]; [self setupTabsBar];
...@@ -931,7 +931,7 @@ ...@@ -931,7 +931,7 @@
return; return;
} }
[APIClient fetchCancelAppointment:self.appointmentData[@"id"] [APIClient requestCancelAppointment:self.appointmentData[@"id"]
reason:remarks reason:remarks
completion:^(NSDictionary *data, NSError *error) completion:^(NSDictionary *data, NSError *error)
{ {
...@@ -965,8 +965,8 @@ ...@@ -965,8 +965,8 @@
}]; }];
} }
-(void) fetchGeneralInfo { -(void) requestGeneralInfo {
[APIClient fetchGeneralInfo:^(NSDictionary *data, NSError *error) { [APIClient requestGeneralInfo:^(NSDictionary *data, NSError *error) {
if (error) return; if (error) return;
NSDictionary *generalInfo = data[@"Data"]; NSDictionary *generalInfo = data[@"Data"];
self.floorPlanImage = generalInfo[@"image"]; self.floorPlanImage = generalInfo[@"image"];
......
...@@ -138,7 +138,7 @@ ...@@ -138,7 +138,7 @@
[self setupListingView]; [self setupListingView];
[self setupFilterOverlay]; [self setupFilterOverlay];
[self setupLoadingOverlay]; [self setupLoadingOverlay];
[self fetchDashboardInfo]; [self requestDashboardInfo];
} }
#pragma mark - Top Bar #pragma mark - Top Bar
...@@ -679,7 +679,7 @@ ...@@ -679,7 +679,7 @@
} }
- (void)onRefresh { - (void)onRefresh {
[self fetchDashboardInfo]; [self requestDashboardInfo];
} }
#pragma mark - Bottom Button #pragma mark - Bottom Button
...@@ -924,10 +924,10 @@ ...@@ -924,10 +924,10 @@
} }
#pragma mark - api #pragma mark - api
- (void)fetchDashboardInfo { - (void)requestDashboardInfo {
[self.loadingView startAnimating]; [self.loadingView startAnimating];
[APIClient fetchDashboardInfo:^(NSDictionary *data, NSError *error) { [APIClient requestDashboardInfo:^(NSDictionary *data, NSError *error) {
[self.loadingView stopAnimating]; [self.loadingView stopAnimating];
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#import "GeneralInfoViewController.h" #import "GeneralInfoViewController.h"
#import "AccessItemViewController.h" #import "AccessItemViewController.h"
#import "OfflineSyncManager.h" #import "OfflineSyncManager.h"
#import "LocalStorage.h"
@interface DashboardViewController () @interface DashboardViewController ()
...@@ -81,7 +82,6 @@ ...@@ -81,7 +82,6 @@
NSLog(@"dashboard.drawerController = %@", self.drawerController); NSLog(@"dashboard.drawerController = %@", self.drawerController);
// [[OfflineSyncManager shared] clearOfflineQueue]; // [[OfflineSyncManager shared] clearOfflineQueue];
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
...@@ -113,13 +113,13 @@ ...@@ -113,13 +113,13 @@
__block NSDictionary *announcementData = nil; __block NSDictionary *announcementData = nil;
dispatch_group_enter(group); dispatch_group_enter(group);
[APIClient fetchDashboardInfo:^(NSDictionary *data, NSError *error) { [APIClient requestDashboardInfo:^(NSDictionary *data, NSError *error) {
if (!error) dashboardData = data; if (!error) dashboardData = data;
dispatch_group_leave(group); dispatch_group_leave(group);
}]; }];
dispatch_group_enter(group); dispatch_group_enter(group);
[APIClient fetchAnnouncement:^(NSDictionary *data, NSError *error) { [APIClient requestAnnouncement:^(NSDictionary *data, NSError *error) {
if (!error) announcementData = data; if (!error) announcementData = data;
dispatch_group_leave(group); dispatch_group_leave(group);
}]; }];
...@@ -593,7 +593,7 @@ ...@@ -593,7 +593,7 @@
NSDictionary *appData = data[@"AppData"]; NSDictionary *appData = data[@"AppData"];
if (![appData[@"status"] isEqualToString:@"success"]) { if (![appData[@"status"] isEqualToString:@"success"]) {
NSLog(@"Announcement fetch failed: %@", appData[@"message"]); NSLog(@"Announcement request failed: %@", appData[@"message"]);
return; return;
} }
......
...@@ -83,7 +83,7 @@ typedef struct { ...@@ -83,7 +83,7 @@ typedef struct {
self.documentsContainer.clipsToBounds = YES; self.documentsContainer.clipsToBounds = YES;
self.formsContainer.clipsToBounds = YES; self.formsContainer.clipsToBounds = YES;
[self fetchGeneralInfo]; [self requestGeneralInfo];
[self setupTopBar]; [self setupTopBar];
[self setupTabControl]; [self setupTabControl];
[self setupScrollView]; [self setupScrollView];
...@@ -540,8 +540,8 @@ typedef struct { ...@@ -540,8 +540,8 @@ typedef struct {
} }
#pragma mark - api #pragma mark - api
- (void)fetchGeneralInfo { - (void)requestGeneralInfo {
[APIClient fetchGeneralInfo:^(NSDictionary *data, NSError *error) { [APIClient requestGeneralInfo:^(NSDictionary *data, NSError *error) {
if (error || !data) { if (error || !data) {
NSLog(@"❌ General info error: %@", error.localizedDescription); NSLog(@"❌ General info error: %@", error.localizedDescription);
return; return;
......
...@@ -67,11 +67,11 @@ ...@@ -67,11 +67,11 @@
} }
- (void)handleGetUnitPlan { - (void)handleGetUnitPlan {
NSLog(@"🌐 Fetching Unit Plan data..."); NSLog(@"🌐 requesting Unit Plan data...");
[APIClient fetchGetUnitPlan:^(NSDictionary *data, NSError *error) { [APIClient requestGetUnitPlan:^(NSDictionary *data, NSError *error) {
if (error) { if (error) {
NSLog(@"❌ Unit Plan fetch failed: %@", error.localizedDescription); NSLog(@"❌ Unit Plan request failed: %@", error.localizedDescription);
return; return;
} }
...@@ -165,7 +165,6 @@ ...@@ -165,7 +165,6 @@
}]; }];
} }
- (void)highlightExistingIssueAtCoordinates:(CGFloat)x Y:(CGFloat)y { - (void)highlightExistingIssueAtCoordinates:(CGFloat)x Y:(CGFloat)y {
NSLog(@"📍 Highlighting existing issue at (%.2f, %.2f)", x, y); NSLog(@"📍 Highlighting existing issue at (%.2f, %.2f)", x, y);
...@@ -702,20 +701,19 @@ ...@@ -702,20 +701,19 @@
} }
if (self.locationID) { if (self.locationID) {
NSLog(@"📡 Fetching settings for location %@ and plan %@", self.locationID, self.planID); NSLog(@"📡 requesting settings for location %@ and plan %@", self.locationID, self.planID);
[self handleSettingsByLocation:self.locationID planID:self.planID]; [self handleSettingsByLocation:self.locationID planID:self.planID];
} else { } else {
NSLog(@"⚠️ No match found for %@", self.selectedLocation); NSLog(@"⚠️ No match found for %@", self.selectedLocation);
} }
} }
- (void)handleSettingsByLocation:(NSString *)locationID planID:(NSString *)planID { - (void)handleSettingsByLocation:(NSString *)locationID planID:(NSString *)planID {
[APIClient fetchSettingsByLocation:locationID [APIClient requestSettingsByLocation:locationID
projectID:@"8" projectID:@"8"
completion:^(NSDictionary *data, NSError *error) { completion:^(NSDictionary *data, NSError *error) {
if (error) { if (error) {
NSLog(@"❌ Error fetching settings: %@", error); NSLog(@"❌ Error requesting settings: %@", error);
return; return;
} }
......
...@@ -126,10 +126,10 @@ ...@@ -126,10 +126,10 @@
#pragma mark - API request/response #pragma mark - API request/response
- (void)handleIssues { - (void)handleIssues {
[APIClient fetchHistory:self.issueID [APIClient requestHistory:self.issueID
completion:^(NSDictionary *data, NSError *error) { completion:^(NSDictionary *data, NSError *error) {
if (error) { if (error) {
NSLog(@"❌ Error fetching history: %@", error); NSLog(@"❌ Error requesting history: %@", error);
return; return;
} }
......
...@@ -298,11 +298,11 @@ ...@@ -298,11 +298,11 @@
#pragma mark - Networking #pragma mark - Networking
- (void)handleGetIssue { - (void)handleGetIssue {
NSLog(@"🌐 Fetching Issue data..."); NSLog(@"🌐 requesting Issue data...");
[APIClient fetchIssues:^(NSDictionary *data, NSError *error) { [APIClient requestIssues:^(NSDictionary *data, NSError *error) {
if (error) { if (error) {
NSLog(@"❌ Issue fetch failed: %@", error.localizedDescription); NSLog(@"❌ Issue request failed: %@", error.localizedDescription);
return; return;
} }
......
...@@ -174,7 +174,7 @@ ...@@ -174,7 +174,7 @@
[self setupSearchBar]; [self setupSearchBar];
[self setupTableView]; [self setupTableView];
[self setupBottomBar]; [self setupBottomBar];
[self fetchIssues]; [self requestIssues];
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
...@@ -382,8 +382,8 @@ ...@@ -382,8 +382,8 @@
} }
#pragma mark - Data #pragma mark - Data
- (void)fetchIssues { - (void)requestIssues {
[APIClient fetchIssues:^(NSDictionary *data, NSError *error) { [APIClient requestIssues:^(NSDictionary *data, NSError *error) {
if (error) return; if (error) return;
NSArray *allIssues = data[@"Data"] ?: @[]; NSArray *allIssues = data[@"Data"] ?: @[];
......
...@@ -264,7 +264,7 @@ ...@@ -264,7 +264,7 @@
- (void)requestDeleteIssue:(NSString *)issueID remarks:(NSString *)remarks { - (void)requestDeleteIssue:(NSString *)issueID remarks:(NSString *)remarks {
NSLog(@"🚀 Sending DELETE ISSUE for ID=%@, remarks=%@", issueID, remarks); NSLog(@"🚀 Sending DELETE ISSUE for ID=%@, remarks=%@", issueID, remarks);
[APIClient fetchDeleteIssue:issueID remarks:remarks completion:^(NSDictionary *data, NSError *error) { [APIClient requestDeleteIssue:issueID remarks:remarks completion:^(NSDictionary *data, NSError *error) {
if (error) { if (error) {
NSLog(@"Error %@", error.localizedDescription); NSLog(@"Error %@", error.localizedDescription);
return; return;
...@@ -301,7 +301,7 @@ ...@@ -301,7 +301,7 @@
-(void)requestVoidIssue:(NSArray *)ids remarks:(NSString *)remarks { -(void)requestVoidIssue:(NSArray *)ids remarks:(NSString *)remarks {
NSLog(@"🚀 Sending VOID ISSUE for ID=%@, remarks=%@", self.selectedIssues, remarks); NSLog(@"🚀 Sending VOID ISSUE for ID=%@, remarks=%@", self.selectedIssues, remarks);
[APIClient fetchVoidIssue:ids [APIClient requestVoidIssue:ids
remarks:remarks remarks:remarks
completion:^(NSDictionary *data, NSError *error) { completion:^(NSDictionary *data, NSError *error) {
if (error) { if (error) {
......
//// SyncEngine.h
//
//#import <Foundation/Foundation.h>
//@interface SyncEngine : NSObject
//
//@property (nonatomic, assign) BOOL submitPending;
//@property (nonatomic, assign) BOOL downloadUnits;
//
//- (void)startWithProgress:(SyncProgressBlock)progress
// completion:(SyncCompletionBlock)completion;
//
//@end
//
//// SyncEngine.mm
//
//#import "SyncEngine.h"
//#import "APIClient.h"
//#import "NetworkManager.h"
//
//@interface SyncEngine ()
//
//// Callbacks
//@property (nonatomic, copy) SyncProgressBlock progressBlock;
//@property (nonatomic, copy) SyncCompletionBlock completionBlock;
//
//// Progress tracking
//@property (nonatomic, assign) NSInteger currentStep;
//@property (nonatomic, assign) NSInteger totalSteps;
//
//@end
//
//@implementation SyncEngine
//
//#pragma mark - Public Entry Point
//
//- (void)startWithProgress:(SyncProgressBlock)progress
// completion:(SyncCompletionBlock)completion {
//
// self.progressBlock = progress;
// self.completionBlock = completion;
//
// self.currentStep = 0;
// self.totalSteps = [self calculateTotalSteps];
//
// [self stepCheckNetwork];
//}
//
//#pragma mark - Step Count
//
//- (NSInteger)calculateTotalSteps {
// NSInteger steps = 1; // check network
//
// if (self.submitPending) {
// steps += 1; // submit pending
// }
//
// if (self.downloadUnits) {
// steps += 1; // download data
// }
//
// steps += 1; // finalize
//
// return steps;
//}
//
//#pragma mark - Step 1: Network Check
//
//- (void)stepCheckNetwork {
// [self reportProgress:@"Checking network"];
//
// if (![NetworkManager.sharedManager isConnected]) {
// NSError *error =
// [NSError errorWithDomain:@"Sync"
// code:-1009
// userInfo:@{
// NSLocalizedDescriptionKey :
// @"No internet connection"
// }];
// [self finish:NO error:error];
// return;
// }
//
// if (self.submitPending) {
// [self stepSubmitPending];
// } else if (self.downloadUnits) {
// [self stepDownloadCommonAreas];
// } else {
// [self stepFinalize];
// }
//}
//
//#pragma mark - Step 2: Submit Pending Offline Items
//
//- (void)stepSubmitPending {
// [self reportProgress:@"Submitting pending items"];
//
// __weak typeof(self) weakSelf = self;
//
// [self submitPendingItemsWithCompletion:^(BOOL success, NSError *error) {
// __strong typeof(weakSelf) self = weakSelf;
//
// if (!success) {
// [self finish:NO error:error];
// return;
// }
//
// if (self.downloadUnits) {
// [self stepDownloadCommonAreas];
// } else {
// [self stepFinalize];
// }
// }];
//}
//
//#pragma mark - Step 3: Download Data
//
//- (void)stepDownloadCommonAreas {
// [self reportProgress:@"Downloading common areas"];
//
// __weak typeof(self) weakSelf = self;
//
// [APIClient fetchCommonArea:^(NSDictionary *data, NSError *error) {
// __strong typeof(weakSelf) self = weakSelf;
//
// if (error) {
// [self finish:NO error:error];
// return;
// }
//
// [self persistCommonAreas:data];
// [self stepFinalize];
// }];
//}
//
//#pragma mark - Step 4: Finalize
//
//- (void)stepFinalize {
// [self reportProgress:@"Finalizing sync"];
// [self finalizeSync];
// [self finish:YES error:nil];
//}
//
//#pragma mark - Progress & Completion Helpers
//
//- (void)reportProgress:(NSString *)message {
// self.currentStep++;
//
// if (self.progressBlock) {
// self.progressBlock(self.currentStep,
// self.totalSteps,
// message);
// }
//}
//
//- (void)finish:(BOOL)success error:(NSError *)error {
// if (self.completionBlock) {
// self.completionBlock(success, error);
// }
//
// // Clean up references
// self.progressBlock = nil;
// self.completionBlock = nil;
//}
//
//#pragma mark - Internal Hooks (Implement These)
//
//- (void)submitPendingItemsWithCompletion:(void (^)(BOOL success, NSError *error))completion {
// // TODO:
// // - Query offline table
// // - Upload ONE item at a time
// // - Update local DB on success/failure
// // - Recursively continue until empty
// // - Call completion when done
//}
//
//- (void)persistCommonAreas:(NSDictionary *)data {
// // TODO:
// // Save common areas into local storage / DB
//}
//
//- (void)finalizeSync {
// // TODO:
// // - Update last sync timestamp
// // - Persist sync success state
//}
//
//@end
// SyncHistoryViewController.mm // SyncHistoryViewController.mm
#import "SyncHistoryViewController.h" #import "SyncHistoryViewController.h"
#import "OfflineSyncManager.h"
typedef NS_ENUM(NSInteger, HistorySyncStatus) { typedef NS_ENUM(NSInteger, HistorySyncStatus) {
HistorySyncStatusSuccess, HistorySyncStatusSuccess,
...@@ -14,6 +15,7 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -14,6 +15,7 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
@property (nonatomic, strong) NSString *uploadedOn; @property (nonatomic, strong) NSString *uploadedOn;
@property (nonatomic, strong) NSString *actionMade; @property (nonatomic, strong) NSString *actionMade;
@property (nonatomic, assign) HistorySyncStatus status; @property (nonatomic, assign) HistorySyncStatus status;
@property (nonatomic, strong) NSDictionary *raw;
@end @end
@implementation HistorySyncItem @implementation HistorySyncItem
...@@ -139,7 +141,6 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -139,7 +141,6 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
@property (nonatomic, strong) NSArray<HistorySyncItem *> *filteredItems; @property (nonatomic, strong) NSArray<HistorySyncItem *> *filteredItems;
@property (nonatomic, assign) NSInteger selectedTab; @property (nonatomic, assign) NSInteger selectedTab;
@end @end
@implementation SyncHistoryViewController @implementation SyncHistoryViewController
...@@ -157,7 +158,13 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -157,7 +158,13 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
[self setupEmptyState]; [self setupEmptyState];
[self setupBottomButton]; [self setupBottomButton];
[self loadMockData]; [self loadHistoryData];
[self applyFilter];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self loadHistoryData];
[self applyFilter]; [self applyFilter];
} }
...@@ -185,18 +192,18 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -185,18 +192,18 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO; self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.titleLabel]; [self.headerView addSubview:self.titleLabel];
self.shareButton = [UIButton buttonWithType:UIButtonTypeSystem]; // self.shareButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.shareButton setTitle:@"Share to Email" forState:UIControlStateNormal]; // [self.shareButton setTitle:@"Share to Email" forState:UIControlStateNormal];
[self.shareButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; // [self.shareButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
self.shareButton.layer.borderColor = UIColor.whiteColor.CGColor; // self.shareButton.layer.borderColor = UIColor.whiteColor.CGColor;
self.shareButton.layer.borderWidth = 0.5; // self.shareButton.layer.borderWidth = 0.5;
self.shareButton.layer.cornerRadius = 14; // self.shareButton.layer.cornerRadius = 14;
[self.shareButton addTarget:self // [self.shareButton addTarget:self
action:@selector(onShare) // action:@selector(onShare)
forControlEvents:UIControlEventTouchUpInside]; // forControlEvents:UIControlEventTouchUpInside];
self.shareButton.titleLabel.font = [UIFont systemFontOfSize:14]; // self.shareButton.titleLabel.font = [UIFont systemFontOfSize:14];
self.shareButton.translatesAutoresizingMaskIntoConstraints = NO; // self.shareButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.shareButton]; // [self.headerView addSubview:self.shareButton];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[self.headerView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], [self.headerView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
...@@ -212,10 +219,10 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -212,10 +219,10 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor], [self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor], [self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.shareButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8], // [self.shareButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8],
[self.shareButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor], // [self.shareButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.shareButton.heightAnchor constraintEqualToConstant:28], // [self.shareButton.heightAnchor constraintEqualToConstant:28],
[self.shareButton.widthAnchor constraintEqualToConstant:120], // [self.shareButton.widthAnchor constraintEqualToConstant:120],
]]; ]];
} }
...@@ -312,6 +319,43 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -312,6 +319,43 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
]]; ]];
} }
#pragma mark - Data
- (void)loadHistoryData {
NSArray *sections =
[[OfflineSyncManager shared] historyItemsForUI];
[self dumpHistoryToFile:sections];
NSMutableArray *items = [NSMutableArray array];
for (NSDictionary *section in sections) {
NSArray *rows = section[@"items"];
for (NSDictionary *row in rows) {
HistorySyncItem *item = [HistorySyncItem new];
item.unitName = row[@"unitName"];
item.createdBy = row[@"createdBy"];
item.createdOn = row[@"createdOn"];
item.uploadedOn = row[@"uploadedOn"];
item.actionMade = row[@"type"];
NSString *status = row[@"status"];
item.status =
[status isEqualToString:@"FAILED"]
? HistorySyncStatusFailed
: HistorySyncStatusSuccess;
item.raw = row;
[items addObject:item];
}
}
self.allItems = items;
}
// Dummy data // Dummy data
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.filteredItems.count; return self.filteredItems.count;
...@@ -384,6 +428,10 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -384,6 +428,10 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
[self.syncAgainButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [self.syncAgainButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
self.syncAgainButton.enabled = NO; self.syncAgainButton.enabled = NO;
[self.syncAgainButton addTarget:self
action:@selector(onSyncAgain)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.syncAgainButton]; [self.view addSubview:self.syncAgainButton];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
...@@ -472,5 +520,45 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) { ...@@ -472,5 +520,45 @@ typedef NS_ENUM(NSInteger, HistorySyncStatus) {
[self.tableView reloadData]; [self.tableView reloadData];
} }
- (void)onSyncAgain {
for (HistorySyncItem *item in self.allItems) {
if (item.status == HistorySyncStatusFailed) {
[[OfflineSyncManager shared] retryHistoryItem:item.raw];
}
}
NSLog(@"Starting sync again");
// [[OfflineSyncManager shared] startManualSync];
[self loadHistoryData];
[self applyFilter];
}
- (void)dumpHistoryToFile:(id)history {
NSString *docDir =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES).firstObject;
NSString *path =
[docDir stringByAppendingPathComponent:@"sync_history_dump.txt"];
NSString *content =
[NSString stringWithFormat:@"=== SYNC HISTORY DUMP ===\n%@\n",
history];
NSError *error = nil;
BOOL success =
[content writeToFile:path
atomically:YES
encoding:NSUTF8StringEncoding
error:&error];
if (success) {
NSLog(@"📄 History dumped to: %@", path);
} else {
NSLog(@"❌ Failed to dump history: %@", error);
}
}
@end @end
...@@ -195,18 +195,18 @@ typedef NS_ENUM(NSInteger, SyncPendingViewMode) { ...@@ -195,18 +195,18 @@ typedef NS_ENUM(NSInteger, SyncPendingViewMode) {
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO; self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.titleLabel]; [self.headerView addSubview:self.titleLabel];
self.shareButton = [UIButton buttonWithType:UIButtonTypeSystem]; // self.shareButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.shareButton setTitle:@"Share to Email" forState:UIControlStateNormal]; // [self.shareButton setTitle:@"Share to Email" forState:UIControlStateNormal];
[self.shareButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; // [self.shareButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
self.shareButton.layer.borderColor = UIColor.whiteColor.CGColor; // self.shareButton.layer.borderColor = UIColor.whiteColor.CGColor;
self.shareButton.layer.borderWidth = 0.5; // self.shareButton.layer.borderWidth = 0.5;
self.shareButton.layer.cornerRadius = 14; // self.shareButton.layer.cornerRadius = 14;
[self.shareButton addTarget:self // [self.shareButton addTarget:self
action:@selector(onShare) // action:@selector(onShare)
forControlEvents:UIControlEventTouchUpInside]; // forControlEvents:UIControlEventTouchUpInside];
self.shareButton.titleLabel.font = [UIFont systemFontOfSize:14]; // self.shareButton.titleLabel.font = [UIFont systemFontOfSize:14];
self.shareButton.translatesAutoresizingMaskIntoConstraints = NO; // self.shareButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.headerView addSubview:self.shareButton]; // [self.headerView addSubview:self.shareButton];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[self.headerView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor], [self.headerView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
...@@ -222,10 +222,10 @@ typedef NS_ENUM(NSInteger, SyncPendingViewMode) { ...@@ -222,10 +222,10 @@ typedef NS_ENUM(NSInteger, SyncPendingViewMode) {
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor], [self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor], [self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.shareButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8], // [self.shareButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8],
[self.shareButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor], // [self.shareButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.shareButton.heightAnchor constraintEqualToConstant:28], // [self.shareButton.heightAnchor constraintEqualToConstant:28],
[self.shareButton.widthAnchor constraintEqualToConstant:120], // [self.shareButton.widthAnchor constraintEqualToConstant:120],
]]; ]];
} }
......
...@@ -14,7 +14,7 @@ typedef NS_ENUM(NSInteger, SyncProjectScreenState) { ...@@ -14,7 +14,7 @@ typedef NS_ENUM(NSInteger, SyncProjectScreenState) {
static NSString * const kSyncSelectedUnitsKey = @"SYNC_SELECTEDUNITS"; static NSString * const kSyncSelectedUnitsKey = @"SYNC_SELECTEDUNITS";
static NSString * const kProjectListKey = @"PROJECT_LIST"; static NSString * const kProjectListKey = @"PROJECT_LIST";
@interface SyncUnit : NSObject @interface SyncUnit : NSObject <NSSecureCoding>
@property (nonatomic, strong) NSString *planId; @property (nonatomic, strong) NSString *planId;
@property (nonatomic, strong) NSString *displayName; @property (nonatomic, strong) NSString *displayName;
@property (nonatomic, strong) NSDictionary *project; @property (nonatomic, strong) NSDictionary *project;
...@@ -24,6 +24,33 @@ static NSString * const kProjectListKey = @"PROJECT_LIST"; ...@@ -24,6 +24,33 @@ static NSString * const kProjectListKey = @"PROJECT_LIST";
@end @end
@implementation SyncUnit @implementation SyncUnit
+ (BOOL)supportsSecureCoding {
return YES;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.planId forKey:@"planId"];
[coder encodeObject:self.displayName forKey:@"displayName"];
[coder encodeObject:self.project forKey:@"project"];
[coder encodeObject:self.projectId forKey:@"projectId"];
[coder encodeObject:self.projectName forKey:@"projectName"];
[coder encodeBool:self.selected forKey:@"selected"];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
_planId = [coder decodeObjectOfClass:[NSString class] forKey:@"planId"];
_displayName = [coder decodeObjectOfClass:[NSString class] forKey:@"displayName"];
_project = [coder decodeObjectOfClass:[NSDictionary class] forKey:@"project"];
_projectId = [coder decodeObjectOfClass:[NSString class] forKey:@"projectId"];
_projectName = [coder decodeObjectOfClass:[NSString class] forKey:@"projectName"];
_selected = [coder decodeBoolForKey:@"selected"];
}
return self;
}
@end @end
@interface SyncProject : NSObject @interface SyncProject : NSObject
...@@ -445,15 +472,15 @@ didSelectItemAtIndexPath:(NSIndexPath *)indexPath { ...@@ -445,15 +472,15 @@ didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
return; return;
} }
NSLog(@"🌐 No cached PROJECT_LIST, fetching from API"); NSLog(@"🌐 No cached PROJECT_LIST, requesting from API");
[self fetchProjectList]; [self requestProjectList];
} }
- (void)fetchProjectList { - (void)requestProjectList {
[self showLoading:YES]; [self showLoading:YES];
[APIClient fetchProjectList:^(NSDictionary *data, NSError *error) { [APIClient requestProjectList:^(NSDictionary *data, NSError *error) {
// debug // debug
NSString *plainText = [NSString stringWithFormat:@"%@", data]; NSString *plainText = [NSString stringWithFormat:@"%@", data];
...@@ -648,8 +675,11 @@ didSelectItemAtIndexPath:(NSIndexPath *)indexPath { ...@@ -648,8 +675,11 @@ didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
- (void)onDone { - (void)onDone {
NSLog(@"Selected units count: %lu", NSLog(@"Selected units count: %lu",
(unsigned long)self.selectedUnits.count); (unsigned long)self.selectedUnits.count);
[LocalStorage saveArray:self.selectedUnits NSMutableArray *dictArray = [NSMutableArray array];
forKey:@"SELECTED_OFFLINE_UNITS"]; for (SyncUnit *unit in self.selectedUnits) {
[dictArray addObject:[self dictionaryFromUnit:unit]];
}
[LocalStorage saveArray:dictArray forKey:@"SELECTED_OFFLINE_UNITS"];
[self showOfflineUnit]; [self showOfflineUnit];
} }
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#import "SyncHistoryViewController.h" #import "SyncHistoryViewController.h"
#import "SyncPendingViewController.h" #import "SyncPendingViewController.h"
#import "SyncProjectViewController.h" #import "SyncProjectViewController.h"
#import "SyncEngine.h"
#import "LocalStorage.h" #import "LocalStorage.h"
#import "OfflineSyncManager.h"
typedef NS_ENUM(NSInteger, SyncCardType) { typedef NS_ENUM(NSInteger, SyncCardType) {
SyncCardTypeOfflineUnits = 1, SyncCardTypeOfflineUnits = 1,
...@@ -14,6 +14,8 @@ typedef NS_ENUM(NSInteger, SyncCardType) { ...@@ -14,6 +14,8 @@ typedef NS_ENUM(NSInteger, SyncCardType) {
SyncCardTypeHistory SyncCardTypeHistory
}; };
static NSString * const kLastOfflineSyncDateKey = @"LAST_OFFLINE_SYNC_DATE";
@interface SyncScreenViewController () @interface SyncScreenViewController ()
@property (nonatomic, strong) UIView *headerView; @property (nonatomic, strong) UIView *headerView;
...@@ -71,7 +73,7 @@ typedef NS_ENUM(NSInteger, SyncCardType) { ...@@ -71,7 +73,7 @@ typedef NS_ENUM(NSInteger, SyncCardType) {
self.isSyncing = NO; self.isSyncing = NO;
//placeholders //placeholders
self.pendingItemCount = 0; self.pendingItemCount = 1;
self.offlineUnitCount = 1; self.offlineUnitCount = 1;
self.historyCount = 1; self.historyCount = 1;
...@@ -87,6 +89,7 @@ typedef NS_ENUM(NSInteger, SyncCardType) { ...@@ -87,6 +89,7 @@ typedef NS_ENUM(NSInteger, SyncCardType) {
self.pendingItemCount = [self loadPendingItemCount]; self.pendingItemCount = [self loadPendingItemCount];
self.offlineUnitCount = [self loadOfflineUnitCount]; self.offlineUnitCount = [self loadOfflineUnitCount];
self.historyCount = [self loadHistoryItemCount];
[self refreshUI]; [self refreshUI];
} }
...@@ -126,18 +129,9 @@ typedef NS_ENUM(NSInteger, SyncCardType) { ...@@ -126,18 +129,9 @@ typedef NS_ENUM(NSInteger, SyncCardType) {
} }
- (void)updateLastUpdatedLabel { - (void)updateLastUpdatedLabel {
if (!self.lastUpdatedDate) { NSString *dateString = [self lastSyncDisplayString];
self.lastUpdatedLabel.text = @"Last Updated:\n--";
return;
}
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateStyle = NSDateFormatterMediumStyle;
fmt.timeStyle = NSDateFormatterShortStyle;
self.lastUpdatedLabel.text = self.lastUpdatedLabel.text =
[NSString stringWithFormat:@"Last Updated:\n%@", [NSString stringWithFormat:@"Last Updated:\n%@", dateString];
[fmt stringFromDate:self.lastUpdatedDate]];
} }
#pragma mark - Header #pragma mark - Header
...@@ -500,7 +494,6 @@ typedef NS_ENUM(NSInteger, SyncCardType) { ...@@ -500,7 +494,6 @@ typedef NS_ENUM(NSInteger, SyncCardType) {
} }
- (void)onOfflineUnitsTapped { - (void)onOfflineUnitsTapped {
if (self.offlineUnitCount == 0) return;
NSLog(@"Offline Units tapped"); NSLog(@"Offline Units tapped");
SyncProjectViewController *nextVC = [[SyncProjectViewController alloc] init]; SyncProjectViewController *nextVC = [[SyncProjectViewController alloc] init];
...@@ -570,39 +563,48 @@ typedef NS_ENUM(NSInteger, SyncCardType) { ...@@ -570,39 +563,48 @@ typedef NS_ENUM(NSInteger, SyncCardType) {
[self refreshUI]; [self refreshUI];
[self showProgressOverlay]; [self showProgressOverlay];
// SyncEngine *engine = [SyncEngine new]; __weak typeof(self) weakSelf = self;
// engine.submitPending = self.shouldSubmitPending;
// engine.downloadUnits = self.shouldDownloadUnits; // 1️⃣ Manual pending sync
// if (self.shouldSubmitPending) {
// __weak typeof(self) weakSelf = self; NSLog(@"Syncing Pending Items");
//
// [engine startWithProgress:^(NSInteger step, [[OfflineSyncManager shared]
// NSInteger total, processNextItemWithProgress:^(NSInteger step, NSInteger total, NSString *title) {
// NSString *title) {
// self.progressLabel.text =
// weakSelf.progressLabel.text = [NSString stringWithFormat:@"%ld / %ld", step, total];
// [NSString stringWithFormat:@"%@ (%ld/%ld)", self.titleLabel.text = title;
// title, (long)step, (long)total]; self.progressBar.progress =
// total > 0 ? (float)step / (float)total : 0;
// weakSelf.progressBar.progress =
// (float)step / (float)total; } completion:^(BOOL finished) {
//
// } completion:^(BOOL success, NSError *error) { self.pendingItemCount = [self loadPendingItemCount];
// self.historyCount = [self loadHistoryItemCount];
// [weakSelf.syncProgressOverlay removeFromSuperview]; [self refreshUI];
// weakSelf.syncProgressOverlay = nil; }];
// }
// weakSelf.isSyncing = NO;
// // 2️⃣ Unit + image download sync
// if (success) { if (self.shouldDownloadUnits) {
// weakSelf.lastUpdatedDate = [NSDate date]; NSLog(@"Downloading Units");
// } else {
// NSLog(@"❌ Sync failed: %@", error.localizedDescription); [[OfflineSyncManager shared]
// // TODO: show alert startDownloadUnitImagesWithProgress:^(NSInteger completed, NSInteger total) {
// }
// weakSelf.progressLabel.text =
// [weakSelf refreshUI]; [NSString stringWithFormat:@"Downloading Units (%ld/%ld)",
// }]; (long)completed, (long)total];
weakSelf.progressBar.progress =
total > 0 ? (float)completed / (float)total : 0;
} completion:^(BOOL success) {
[weakSelf finishSyncWithSuccess:success];
}];
}
} }
- (void)dismissSyncModal { - (void)dismissSyncModal {
...@@ -630,4 +632,38 @@ typedef NS_ENUM(NSInteger, SyncCardType) { ...@@ -630,4 +632,38 @@ typedef NS_ENUM(NSInteger, SyncCardType) {
return units.count; return units.count;
} }
- (NSInteger)loadHistoryItemCount {
NSArray *units = [LocalStorage loadArrayForKey:@"SYNC_HISTORY_QUEUE"];
return units.count;
}
- (void)finishSyncWithSuccess:(BOOL)success {
[self.syncProgressOverlay removeFromSuperview];
self.syncProgressOverlay = nil;
self.isSyncing = NO;
if (success) {
self.lastUpdatedDate = [NSDate date];
}
[self refreshUI];
}
- (NSString *)lastSyncDisplayString {
NSNumber *ts = [LocalStorage loadObjectForKey:kLastOfflineSyncDateKey];
if (!ts) {
return @"--";
}
NSDate *date = [NSDate dateWithTimeIntervalSince1970:ts.doubleValue];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateStyle = NSDateFormatterMediumStyle;
formatter.timeStyle = NSDateFormatterShortStyle;
return [formatter stringFromDate:date];
}
@end @end
...@@ -6,12 +6,12 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -6,12 +6,12 @@ NS_ASSUME_NONNULL_BEGIN
@interface APIClient : NSObject @interface APIClient : NSObject
+ (void)fetchAccessItem:(NSString *)unitId + (void)requestAccessItem:(NSString *)unitId
completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion; completion:(void(^)(BOOL success, NSDictionary * _Nullable response, NSError * _Nullable error))completion;
+ (void)fetchGetUnitPlan:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; + (void)requestGetUnitPlan:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)fetchSettingsByLocation:(NSString * _Nonnull)locationID + (void)requestSettingsByLocation:(NSString * _Nonnull)locationID
projectID:(NSString * _Nonnull)projectID projectID:(NSString * _Nonnull)projectID
completion:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; completion:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
...@@ -23,9 +23,9 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -23,9 +23,9 @@ NS_ASSUME_NONNULL_BEGIN
images:(NSArray<UIImage *> * _Nullable)images images:(NSArray<UIImage *> * _Nullable)images
completion:(void (^)(NSDictionary * _Nullable response, NSError * _Nullable error))completion; completion:(void (^)(NSDictionary * _Nullable response, NSError * _Nullable error))completion;
+ (void)fetchAppointment:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; + (void)requestAppointment:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)fetchGeneralInfo:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; + (void)requestGeneralInfo:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (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;
...@@ -33,15 +33,15 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -33,15 +33,15 @@ NS_ASSUME_NONNULL_BEGIN
+ (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;
+ (void)fetchCancelAppointment:(id)appointmentId + (void)requestCancelAppointment:(id)appointmentId
reason:(NSString *)reason reason:(NSString *)reason
completion:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; completion:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)fetchDashboardInfo:(void (^)(NSDictionary *data, NSError *error))completion; + (void)requestDashboardInfo:(void (^)(NSDictionary *data, NSError *error))completion;
+ (void)fetchAnnouncement:(void (^)(NSDictionary *data, NSError *error))completion; + (void)requestAnnouncement:(void (^)(NSDictionary *data, NSError *error))completion;
+ (void)fetchHistory:(NSString *)issueID + (void)requestHistory:(NSString *)issueID
completion:(void (^)(NSDictionary *data, NSError *error))completion; completion:(void (^)(NSDictionary *data, NSError *error))completion;
+(void)submitAddInfo:(NSString *)issueID +(void)submitAddInfo:(NSString *)issueID
...@@ -55,23 +55,29 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -55,23 +55,29 @@ NS_ASSUME_NONNULL_BEGIN
mediaType:(NSString *)mediaType mediaType:(NSString *)mediaType
completion:(void (^)(NSDictionary *data, NSError *error))completion; completion:(void (^)(NSDictionary *data, NSError *error))completion;
+ (void)fetchIssues:(void (^)(NSDictionary *data, NSError *error))completion; + (void)requestIssues:(void (^)(NSDictionary *data, NSError *error))completion;
+ (void)fetchVoidIssue:(id)issueID + (void)requestVoidIssue:(id)issueID
remarks:(NSString *)remarks remarks:(NSString *)remarks
completion:(void (^)(NSDictionary *data, NSError *error))completion; completion:(void (^)(NSDictionary *data, NSError *error))completion;
+ (void)fetchDeleteIssue:(id)issueID + (void)requestDeleteIssue:(id)issueID
remarks:(NSString *)remarks remarks:(NSString *)remarks
completion:(void (^)(NSDictionary *data, NSError *error))completion; completion:(void (^)(NSDictionary *data, NSError *error))completion;
+ (void)fetchCommonArea:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; + (void)requestCommonArea:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)fetchGeneralSettings:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; + (void)requestGeneralSettings:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)fetchDefectMatrix:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; + (void)requestDefectMatrix:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)fetchProjectList:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion; + (void)requestProjectList:(void (^)(NSDictionary * _Nullable data, NSError * _Nullable error))completion;
+ (void)requestArrayImage:(NSArray *)imageArray
completion:(void (^)(NSDictionary *data, NSError *error))completion;
+ (void)downloadAndCacheImage:(NSURL *)url
completion:(void (^)(BOOL success))completion;
@end @end
......
...@@ -18,4 +18,8 @@ ...@@ -18,4 +18,8 @@
/// Save array safely (for convenience) /// Save array safely (for convenience)
+ (void)saveArray:(NSArray *)array forKey:(NSString *)key; + (void)saveArray:(NSArray *)array forKey:(NSString *)key;
+ (NSDictionary *)loadDictionaryForKey:(NSString *)key;
+ (void)saveDictionary:(NSDictionary *)dict forKey:(NSString *)key;
@end @end
...@@ -57,4 +57,16 @@ ...@@ -57,4 +57,16 @@
[self saveObject:array forKey:key]; [self saveObject:array forKey:key];
} }
+ (NSDictionary *)loadDictionaryForKey:(NSString *)key {
id object = [self loadObjectForKey:key];
if ([object isKindOfClass:[NSDictionary class]]) {
return object;
}
return nil;
}
+ (void)saveDictionary:(NSDictionary *)dict forKey:(NSString *)key {
[self saveObject:dict forKey:key];
}
@end @end
...@@ -28,9 +28,22 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -28,9 +28,22 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)hasPendingItems; - (BOOL)hasPendingItems;
- (NSArray *)pendingItemsForUI; - (NSArray *)pendingItemsForUI;
- (NSArray *)historyItemsForUI;
- (void)clearOfflineQueue; - (void)clearOfflineQueue;
- (void)processNextItemWithProgress:(void (^)(NSInteger step,
NSInteger total,
NSString *title))progress
completion:(void (^)(BOOL finished))completion;
// Retry failed history item
- (void)retryHistoryItem:(NSDictionary *)historyItem;
// Download Units
- (void)startDownloadUnitImagesWithProgress:(void (^)(NSInteger completed, NSInteger total))progress
completion:(void (^)(BOOL success))completion;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
...@@ -8,32 +8,32 @@ ...@@ -8,32 +8,32 @@
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string> <string>ios-arm64</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string> <string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key> <key>LibraryIdentifier</key>
<string>ios-arm64</string> <string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key> <key>LibraryPath</key>
<string>QmsPluginFramework.framework</string> <string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key> <key>SupportedArchitectures</key>
<array> <array>
<string>arm64</string> <string>arm64</string>
<string>x86_64</string>
</array> </array>
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict> </dict>
</array> </array>
<key>CFBundlePackageType</key> <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