我的Objective-C iOS App上有问题。
我有一个UItableview,其中定义了多行,并从我的后端URL加载了数据
此表视图是一个作业表。让我说在我的后端我有3排这个工作表(摄影师,建筑师和老师)。如果我添加一个新作业(面包师),当我重新启动我的应用程序时,它会在tableview上正确下载(因此应用程序上有4行)。
现在,当我在后端删除作业时,作业不会从iPhone上的表中删除。当用户选择已删除的作业行面临崩溃或错误时,它会给我带来麻烦...要删除它我必须删除应用程序并重新加载它(这真是一团糟)
你会推荐我什么?
非常感谢你的帮助,
最好,大卫
// JobsVC.m
#import "JobsVC.h"
#import "DataProvider.h"
#import "JobsTableViewCell.h"
#import "DBJobs.h"
#import "DBLinkUserJob.h"
#import <MagicalRecord/MagicalRecord.h>
@interface JobsVC ()
@property (weak, nonatomic) IBOutlet UITableView *jobsTableView;
@property (weak, nonatomic) IBOutlet UIButton *okButton;
@property (weak, nonatomic) IBOutlet UIView *selectJobsView;
@property (weak, nonatomic) IBOutlet UILabel *selectJobsTitleLabel;
@property (weak, nonatomic) IBOutlet UILabel *selectJobsDetailsLabel;
@property (strong, nonatomic) NSMutableDictionary *jobsDataSource;
@property (strong, nonatomic) NSMutableArray *selectedJobs;
@property (nonatomic, strong) UIRefreshControl *refreshControl;
@property (strong, nonatomic) NSMutableArray *jobsArray;
@end
@implementation JobsVC
- (void)viewDidLoad {
[super viewDidLoad];
self.selectedJobs = [NSMutableArray new];
self.jobsDataSource = [NSMutableDictionary new];
self.jobsArray = [NSMutableArray new];
self.verifiedHyperjobs = [NSMutableArray new];
[self initialSetup];
[self loadJobs];
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventValueChanged];
[self.jobsTableView addSubview:self.refreshControl];
}
-(void)viewWillAppear:(BOOL)animated{
//Editing header view according to selection mode
if (self.jobsMode == Jobs_Mode_Lb || self.jobsMode == Jobs_Mode_Ad) {
[self.selectJobsView setFrame:CGRectMake(self.selectJobsView.frame.origin.x, self.selectJobsView.frame.origin.x, self.selectJobsView.frame.size.width, 60.0)];
[self.selectJobsTitleLabel setFrame:CGRectMake(self.selectJobsTitleLabel.frame.origin.x, 19.0, self.selectJobsTitleLabel.frame.size.width, 0.0)];
[self.selectJobsDetailsLabel setFrame:CGRectMake(self.selectJobsDetailsLabel.frame.origin.x, 19.0, self.selectJobsDetailsLabel.frame.size.width, 36.0)];
[self.selectJobsTitleLabel setText:@""];
[self.selectJobsDetailsLabel setText:NSLocalizedString(@"jobs_select_ad_lb_jobs", nil)];
[self.selectJobsDetailsLabel setFont:[UIFont fontWithName:@"DIN Alternate" size:18]];
[self.selectJobsDetailsLabel setMinimumScaleFactor:0.6];
}
else{
[self.selectJobsView setFrame:CGRectMake(self.selectJobsView.frame.origin.x, self.selectJobsView.frame.origin.x, self.selectJobsView.frame.size.width, 180.0)];
[self.selectJobsTitleLabel setFrame:CGRectMake(self.selectJobsTitleLabel.frame.origin.x, 19.0, self.selectJobsTitleLabel.frame.size.width, 36.0)];
[self.selectJobsDetailsLabel setFrame:CGRectMake(self.selectJobsDetailsLabel.frame.origin.x, 63.0, self.selectJobsDetailsLabel.frame.size.width, 117.0)];
[self.selectJobsTitleLabel setText:NSLocalizedString(@"jobs_select_title", nil)];
[self.selectJobsTitleLabel setFont:[UIFont fontWithName:@"AWConquerorDidot-Light" size:24]];
[self.selectJobsTitleLabel setMinimumScaleFactor:0.6];
[self.selectJobsDetailsLabel setText:NSLocalizedString(@"jobs_select_details", nil)];
[self.selectJobsDetailsLabel setFont:[UIFont fontWithName:@"DIN Alternate" size:18]];
[self.selectJobsDetailsLabel setMinimumScaleFactor:0.6];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Helpers
- (void)initialSetup {
[self setupNavigationBar:YES];
if (self.jobsMode == Jobs_Mode_Lb || self.jobsMode == Jobs_Mode_Ad || ![LogicManager sharedInstance].currentUserID) {
[self.navigationItem setTitle:NSLocalizedString(@"jobs_ttl", nil)];
} else {
DBUsers *userDB = [DBUsers MR_findFirstByAttribute:@"userID" withValue:[LogicManager sharedInstance].currentUserID];
[self.navigationItem setTitle:userDB.login];
}
[self.navigationController.navigationBar
setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor],
NSFontAttributeName : [UIFont fontWithName:@"AWConquerorDidot-Light" size:24]}];
[self.okButton setTitle:NSLocalizedString(@"button_ok", nil) forState:UIControlStateNormal];
[self.okButton.titleLabel setFont:[UIFont fontWithName:@"DIN Alternate" size:16]];
}
#pragma mark - Logic
- (void)loadJobs {
[self.jobsDataSource removeAllObjects];
[self.jobsArray removeAllObjects];
if (!self.selectedJobs.count) {
if (self.jobsMode == Jobs_Mode_Lb) {
self.selectedJobs = [DataProvider sharedInstance].lbJobsArray;
} else if (self.jobsMode == Jobs_Mode_Ad) {
self.selectedJobs = [DataProvider sharedInstance].adJobsArray;
} else {
self.selectedJobs = [DataProvider sharedInstance].userJobsArray;
}
}
// NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(isM == NO)"];
// NSMutableArray *sources = [[DBJobs MR_findAllWithPredicate:predicate] mutableCopy];
// NSMutableArray *sources = [[DBJobs MR_findAll] mutableCopy];
NSMutableArray* sources = [[[[DBJobs MR_findAll] mutableCopy] sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
if([[LogicManager sharedInstance].deviceLanguage containsString:@"fr"]){
return [NSLocalizedString([(DBJobs*)a name_fr],nil) caseInsensitiveCompare:NSLocalizedString([(DBJobs*)b name_fr],nil)];
}
else{
return [NSLocalizedString([(DBJobs*)a name],nil) caseInsensitiveCompare:NSLocalizedString([(DBJobs*)b name],nil)];
}
}] mutableCopy];
for (DBJobs *jobDB in sources) {
NSString *jobName = [[LogicManager sharedInstance].deviceLanguage containsString:@"fr"] ? jobDB.name_fr : jobDB.name;
NSString *jobIndex = [[jobName substringToIndex:1] uppercaseString];
if (![[[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] containsObject:jobIndex]) {
NSMutableArray *mutableArray = [NSMutableArray new];
[mutableArray addObject:jobDB];
[self.jobsDataSource setValue:mutableArray forKey:jobIndex];
} else {
NSMutableArray *mutableArray = [self.jobsDataSource objectForKey:jobIndex];
if (![mutableArray containsObject:jobDB]) {
[mutableArray addObject:jobDB];
[self.jobsDataSource setValue:mutableArray forKey:jobIndex];
}
}
[self.jobsArray addObject:jobDB];
}
sortedKeys = [[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)];
}
- (void)refreshData {
[[ServiceManager sharedInstance] loadJobsWithCompletion:^(NSArray *responce, NSString *errorMessage) {
if ([self.refreshControl isRefreshing]) {
[self.refreshControl endRefreshing];
}
if (errorMessage) {
[[LogicManager sharedInstance] showAlertWithTitleKey:@"api_msg_error" AndMessage:errorMessage];
} else {
[self loadJobs];
}
}];
}
#pragma mark - Actions
- (IBAction)okButtonPressed:(id)sender {
if(self.selectedJobs.count == 0){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"jobs_select_title", nil) message:NSLocalizedString(@"jobs_no_job_msg", nil) delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
else{
if (self.jobsMode != Jobs_Mode_Lb && self.jobsMode != Jobs_Mode_Ad) {
BOOL hasSelectedHyperJob = FALSE;
NSMutableArray *tempArray = [NSMutableArray new];
NSMutableArray *tempHyperArray = [NSMutableArray new];
//Get selected hyperjobs for request
for(NSString *jobID in self.selectedJobs){
DBJobs *jobDB = [DBJobs MR_findFirstByAttribute:@"jobID" withValue:jobID];
if([jobDB.isM boolValue]){
hasSelectedHyperJob = TRUE;
[tempArray addObject:jobID];
}
}
//Check for verified hyperjobs in selected hyperjobs and remove them from request
for(NSString *jobID in tempArray){
for(NSString* selectedJobID in self.verifiedHyperjobs){
if([selectedJobID isEqualToString:jobID]){
[tempArray removeObject:jobID];
}
}
}
//Check for removed hyperjobs
for(NSString *jobID in self.verifiedHyperjobs){
BOOL isSelected = FALSE;
for(NSString* selectedJobID in self.selectedJobs){
if([selectedJobID isEqualToString:jobID]){
isSelected = TRUE;
}
}
if(isSelected == FALSE){
[tempHyperArray addObject:jobID];
}
}
//Remove deleted hyperjob
for (NSString *jobID in tempHyperArray){
[self.verifiedHyperjobs removeObject:jobID];
}
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.color = [UIColor whiteColor];
hud.labelColor = [UIColor blackColor];
hud.detailsLabelColor = [UIColor blackColor];
hud.mode = MBProgressHUDModeCustomView;
hud.customView = [LogicManager sharedInstance].HudActivity;
hud.dimBackground = YES;
//Request hyperjob
BOOL shouldReturn = FALSE;
for (NSString *jobID in tempArray){
[self.selectedJobs removeObject:jobID];
if([self.selectedJobs count] == 0){
//adding "Awaiting Status Verification" job
[self.selectedJobs addObject:@"57"];
}
shouldReturn = TRUE;
NSString *lang = @"en";
if([[LogicManager sharedInstance].deviceLanguage containsString:@"fr"]){
lang = @"fr";
}
[[ServiceManager sharedInstance] requestHyperjob:jobID forEmail:self.userEmail userID:self.userID language:lang lastName:self.userLastName andFirstName:self.userFirstName completion:^(id responce, NSString *errorMessage) {
if (!errorMessage && [responce[@"error"] intValue] == 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"hint_hyperjobs", nil) message:NSLocalizedString(@"hint_hyperjobs_txt", nil) delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
//show success
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"hint_hyperjobs", nil) message:NSLocalizedString(@"api_msg_error", nil) delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
}
}];
}
if(shouldReturn == TRUE){
return;
}
}
NSLog(@" selected jobs : %@", self.selectedJobs);
if (self.jobsMode == Jobs_Mode_Lb) {
[DataProvider sharedInstance].lbJobsArray = self.selectedJobs;
} else if (self.jobsMode == Jobs_Mode_Ad) {
[DataProvider sharedInstance].adJobsArray = self.selectedJobs;
} else {
[DataProvider sharedInstance].userJobsArray = self.selectedJobs;
}
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark - UITableView Delegate & DataSource1
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
JobsTableViewCell*cell = (JobsTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
// NSString *sectionTitle = [[[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.section];
// NSMutableArray *array = [self.jobsDataSource objectForKey:sectionTitle];
DBJobs *jobDB = [self.jobsArray objectAtIndex:indexPath.row];
[cell.jobNameLabel setFont:[UIFont fontWithName:@"DIN Alternate Bold" size:16]];
[cell.jobNameLabel setTextColor:[UIColor colorWithRed:(142.0/255.0) green:(142.0/255.0) blue:(142.0/255.0) alpha:1.0]];
if ([self.selectedJobs containsObject:jobDB.jobID]) {
if([jobDB.isM boolValue]){
[cell.jobNameLabel setTextColor:[UIColor colorWithRed:(210.0/255.0) green:(196.0/255.0) blue:(169.0/255.0) alpha:1.0]];
}
[self.selectedJobs removeObject:jobDB.jobID];
} else {
[self.selectedJobs addObject:jobDB.jobID];
[cell.jobNameLabel setFont:[UIFont fontWithName:@"DIN Alternate" size:20]];
if([jobDB.isM boolValue]){
[cell.jobNameLabel setTextColor:[UIColor colorWithRed:(168.0/255.0) green:(148.0/255.0) blue:(109.0/255.0) alpha:1.0]];
}
else{
[cell.jobNameLabel setTextColor:[UIColor blackColor]];
}
}
NSLog(@"selected jobs : %@", self.selectedJobs);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// return [[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)].count;
return 1;
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 40;
}
//- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
// return [[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)];
//}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// NSString *sectionTitle = [[[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] objectAtIndex:section];
// NSArray *array = [self.jobsDataSource objectForKey:sectionTitle];
return [self.jobsArray count];
}
//- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
// NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:0 inSection:index];
// [tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
// return index;
//}
//
//- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
// return [[[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] objectAtIndex:section];
//}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
JobsTableViewCell*cell = (JobsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"JobsTableViewCell"];
//NSString *sectionTitle = [sortedKeys objectAtIndex:indexPath.section];
// NSString *sectionTitle = [[[self.jobsDataSource allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] objectAtIndex:indexPath.section];
// NSMutableArray *array = [self.jobsDataSource objectForKey:sectionTitle];
DBJobs *jobDB = [self.jobsArray objectAtIndex:indexPath.row];
cell.width = self.view.width;
cell.jobNameLabel.text = [[LogicManager sharedInstance].deviceLanguage containsString:@"fr"] ? jobDB.name_fr : jobDB.name;
[cell.jobNameLabel setFont:[UIFont fontWithName:@"DIN Alternate Bold" size:16]];
[cell.jobNameLabel setTextColor:[UIColor colorWithRed:(142.0/255.0) green:(142.0/255.0) blue:(142.0/255.0) alpha:1.0]];
[cell setUserInteractionEnabled:TRUE];
if ([self.selectedJobs containsObject:jobDB.jobID]) {
[cell.jobNameLabel setFont:[UIFont fontWithName:@"DIN Alternate" size:20]];
if([jobDB.isM boolValue]){
[cell.jobNameLabel setTextColor:[UIColor colorWithRed:(168.0/255.0) green:(148.0/255.0) blue:(109.0/255.0) alpha:1.0]];
if(self.jobsMode != Jobs_Mode_Ad && self.jobsMode != Jobs_Mode_Lb){
[cell setUserInteractionEnabled:FALSE];
}
}
else{
[cell.jobNameLabel setTextColor:[UIColor blackColor]];
}
// [cell.contentView setBackgroundColor:[UIColor clearColor]];
} else {
// [cell.contentView setBackgroundColor:[UIColor grayColor]];
if([jobDB.isM boolValue]){
[cell.jobNameLabel setTextColor:[UIColor colorWithRed:(210.0/255.0) green:(196.0/255.0) blue:(169.0/255.0) alpha:1.0]];
}
}
return cell;
}
#pragma mark - UIAlertView Delegate Methods
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex{
[self okButtonPressed:0];
}
@end
&#13;
// ServiceManager.m
#import "ServiceManager.h"
#import "LogicManager.h"
#import <MagicalRecord/MagicalRecord.h>
#import "DataProvider.h"
#import "DBJobs.h"
#import "Constants.h"
static NSString * const ApiJobsURLString = @"/api/v1/jobs/";
#pragma mark - JOBS
- (void)loadJobsWithCompletion:(void (^)(NSArray *responce,NSString * error))completion {
if (!self.isConnected) {
completion(nil, NSLocalizedString(@"msg_internet",nil));
return;
}
[self GET:ApiJobsURLString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
if (completion) {
if ([responseObject isKindOfClass:[NSDictionary class]]) {
NSArray *arrayResponce = [responseObject objectForKey:@"jobs"];
for (NSDictionary *dict in arrayResponce) {
[self saveJob:dict];
}
}
completion(responseObject, nil);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
if (!errorData) {
(error.code == -1005 || error.code == -1009) ? completion(nil, NSLocalizedString(@"msg_internet",nil)) : completion(nil, NSLocalizedString(error.description,nil));
return;
}
NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData: errorData options:kNilOptions error:nil];
NSString *errorMessage = [serializedData objectForKey:@"message"];
if (completion) {
completion(nil, NSLocalizedString(errorMessage,nil));
}
}];
}
&#13;