简体   繁体   English

为iPhone日历应用程序存储数据的最佳方法

[英]Best way to store data for an iPhone calendaring app

I am working on an iPhone app. 我正在使用iPhone应用程序。 It is a Enterprise calendaring app for my agency. 这是我的代理机构的企业日历应用程序。 We have a RESTful API backend connected to a web application where the appointments are entered. 我们有一个RESTful API后端连接到输入约会的Web应用程序。 The appointments for an individual are to show up on that user's iPhone. 个人的约会将显示在该用户的iPhone上。 Data is sent by XML. 数据通过XML发送。 There are only 3 or 4 appointments per day and less than 10 fields per record, so not a lot of data is transferred at a time (just the selected day's information). 每天只有3或4个约会,每条记录少于10个字段,因此一次不会传输大量数据(只是所选日期的信息)。

I tried to design this with an array on the iPhone for the parsed data, but the security checking on the web server makes the application time out when loading the data, and I didn't handle the asynchronous processing well. 我尝试使用iPhone上的数组设计用于解析的数据,但是Web服务器上的安全性检查使应用程序在加载数据时超时,因此我无法很好地处理异步处理。

Now I'm wondering if I'm even approaching the problem correctly. 现在我想知道我是否正在正确地解决问题。 Would it be better to use Core Data to store the appointments and then work to update the Core Data store in the background? 使用Core Data存储约会,然后在后台更新Core Data存储会更好吗? I know I need to update the data outside of the loading the table process. 我知道我需要在加载表过程之外更新数据。 I'm just at a loss for the best way to approach this. 我不知所措地寻求最佳解决方案。

I have looked through the site for information as to how to approach this. 我浏览了该网站,以获取有关如何进行此操作的信息。 I have tried looking in books. 我试图看书。 Any help would be appreciated. 任何帮助,将不胜感激。

Security.h 安全性

typedef void (^touchIDComplete)(BOOL);
typedef void (^fileExists)(BOOL);
typedef void (^sessionVerify)(BOOL);
typedef void (^parsingData)(BOOL);
typedef void (^touchIDSuccess)(BOOL);
typedef void (^sessionRetrieved)(BOOL);
typedef void (^touchIDComplete)(BOOL);
typedef void (^sessionReading)(BOOL);
typedef void (^fillArray)(BOOL);
typedef void (^getTheData)(NSData *myData, NSError *error);
typedef void (^gettingESNBlock)(NSString *myESN, NSString *newSession, BOOL success, NSError *error);
typedef void (^checkingESNBlock)(NSString *myESN, NSString *sessionInfo, BOOL success, NSError *error);


@interface Security : NSObject

@property (strong, nonatomic) NSArray *types;
@property (strong, nonatomic) NSArray *esn;
@property (strong, nonatomic) NSString *idfv;
@property (strong, nonatomic) NSData *parseData;
@property (strong, nonatomic) NSString *sessionDetail;
@property (strong, nonatomic) NSString *loginFinished;
@property (strong, nonatomic) NSMutableURLRequest *request;
@property (atomic) NSString *passESN;

- (void)waitForData:(sessionVerify)compblock;
- (void)waitForFile:(fileExists)compblock;
- (void)waitForESN:(parsingData)compblock;
- (void)findESN:(gettingESNBlock)callback;
- (void)checkThumb:(touchIDSuccess)compblock;
- (void)readIt:(sessionRetrieved)compblock;
- (void)readNewSession:(sessionReading)compblock;
- (void)doTheWork:(NSString *)theESN withSession:(NSString *)newSession withSuccess:(BOOL)success error:(NSError *)error;
- (void)checkESN:(checkingESNBlock)callback;
- (void)checkTheSession:(NSString *)oldESN withSession:(NSString *)oldSession withSuccess:(BOOL)success error:(NSError *)error;
- (void)fillAppointmentData:(fillArray)compblock;
- (void)gettingData:(getTheData)compblock;

@end

Security.m 安全性

@implementation Security

void(^getESNForCallback)(NSString *myESN, NSString *newSession, BOOL success, NSError *error);
void(^checkESNWithCallback)(NSString *myESN, NSString *oldSession, BOOL success, NSError *error);

- (void)waitForFile:(fileExists) compblock {

    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0];
    NSString *fullPath = [documentsDirectoryPath stringByAppendingString:@"/session.txt"];
    compblock([fileManager fileExistsAtPath:fullPath]);
}

- (void) waitForData:(sessionVerify) compblock {
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:self.request
                                        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                            if (error) {
                                                return;
                                            }

                                            if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
                                                NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];

                                                if (statusCode != 200) {
                                                    if (statusCode == 401) {
                                                        // Insert process for thumbprint and session cookie pull
                                                        NSFileManager *fileManagerThree = [NSFileManager defaultManager];
                                                        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
                                                        NSString *sessionPath = [documentsPath stringByAppendingPathComponent:@"session.txt"];
                                                        NSError *error;
                                                        BOOL success = [fileManagerThree removeItemAtPath:sessionPath error:&error];
                                                        if (success) {
                                                        } else {
                                                        }
                                                    } else {
                                                        return;
                                                    }
                                                }
                                            }
                                            self.parseData = data;
                                            compblock (YES);
                                        }];
    [task resume];
}

- (void)waitForESN:(parsingData) compblock {
    ParseTypeXML *myParser = [[ParseTypeXML alloc] initWithData:self.parseData];
    VariableStore *globals = [VariableStore sharedInstance];
    if ([myParser.esn count] == 0) {
        globals.user_esn = @"Error";
        compblock(YES);
    } else {
        globals.user_esn = myParser.esn[0];
        compblock(YES);
    }
}

- (void)findESN:(gettingESNBlock)callback {
    getESNForCallback = callback;
    VariableStore *globals = [VariableStore sharedInstance];
    [self doTheWork:globals.user_esn withSession:globals.sessionInfo withSuccess:YES error:nil];
}

- (void)doTheWork:(NSString *)theESN withSession:(NSString *)newSession withSuccess:(BOOL)success error:(NSError *)error {
    [self checkThumb:^(BOOL finished) {
        if(finished) {
            [self readIt:^(BOOL newFile) {
                if (newFile) {
                    [self readNewSession:^(BOOL seen) {
                        if (seen) {
                            VariableStore *globals = [VariableStore sharedInstance];
                            NSDictionary *cookieProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                                        @"ollie/", NSHTTPCookieDomain,
                                                        @"\\", NSHTTPCookiePath,
                                                        @"Cookie", NSHTTPCookieName,
                                                        globals.sessionInfo, NSHTTPCookieValue,
                                                        nil];
                            NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
                            NSArray *cookieArray = [NSArray arrayWithObject:cookie];
                            NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];

                            NSMutableString *url = [[NSMutableString alloc] initWithString:@"https://company.com/file.php"];

                            NSURL *urlNew = [NSURL URLWithString:url];
                            self.request = [NSMutableURLRequest requestWithURL:urlNew];
                            [self.request setHTTPMethod:@"GET"];
                            [self.request setAllHTTPHeaderFields:headers];

                            [self waitForData:^(BOOL dataReceived) {
                                if (dataReceived) {
                                    [self waitForESN:^(BOOL esnFound) {
                                        if (esnFound) {
                                            VariableStore *globals = [VariableStore sharedInstance];
                                            getESNForCallback(globals.user_esn, globals.sessionInfo, success, error);
                                        }
                                    }];
                                }
                            }];
                        }
                    }];
                }
            }];
        }
    }];
}

- (void)checkThumb:(touchIDSuccess)compblock {
    LAContext *context = [[LAContext alloc] init];
    NSError *error = nil;

    if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
        // Authenticate User
        [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
            localizedReason:@"You need to log in."
                      reply:^(BOOL success, NSError * _Nullable error) {
                          if (success) {
                              NSLog(@"success");
                              compblock(YES);
                          } else {
                              switch (error.code) {
                                  case LAErrorAuthenticationFailed:
                                      break;
                                  case LAErrorUserCancel:
                                      break;
                                  case LAErrorUserFallback:
                                      break;

                                  default:
                                      break;
                              }
                          }
                      }];
    }
}

- (void)readIt:(sessionRetrieved)compblock {
    NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    NSString *url = @"https://company.com/specialstring.php";

    NSMutableString *postText = [[NSMutableString alloc] init];

    [postText appendString:idfv];

    NSString *postBody = [NSString stringWithString:postText];

    XMLPostSecurity *postAction = [[XMLPostSecurity alloc] init];
    VariableStore *globals = [VariableStore sharedInstance];
    globals.sessionInfo = [postAction sendPostRequestToUrl:url withBody:postBody];

    FileSaving *saver = [[FileSaving alloc] init];

    [saver saveSession:globals.sessionInfo];
    compblock(YES);
}

-(void)readNewSession:(sessionReading)compblock {
    NSFileManager *fileManagerTwo;
    NSData *dataBuffer;
    fileManagerTwo = [NSFileManager defaultManager];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *filePath = [documentsDirectory stringByAppendingString:@"/session.txt"];

    dataBuffer = [fileManagerTwo contentsAtPath:filePath];
    VariableStore *globals = [VariableStore sharedInstance];
    globals.sessionInfo = [[NSString alloc] initWithData:dataBuffer encoding:(NSASCIIStringEncoding)];
    compblock(YES);
}

- (void)checkESN:(checkingESNBlock)callback {
    checkESNWithCallback = callback;
    VariableStore *globals = [VariableStore sharedInstance];
    [self checkTheSession:globals.user_esn withSession:globals.sessionInfo withSuccess:YES error:nil];
}

- (void)checkTheSession:(NSString *)theESN withSession:(NSString *)oldSession withSuccess:(BOOL)success error:(NSError *)error {
    [self readNewSession:^(BOOL seen) {
        if (seen) {
            VariableStore *globals = [VariableStore sharedInstance];
            NSDictionary *cookieProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                            @"ollie/", NSHTTPCookieDomain,
                                            @"\\", NSHTTPCookiePath,
                                            @"Cookie", NSHTTPCookieName,
                                            globals.sessionInfo, NSHTTPCookieValue,
                                            nil];
            NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
            NSArray *cookieArray = [NSArray arrayWithObject:cookie];
            NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];

            NSMutableString *url = [[NSMutableString alloc] initWithString:@"https://company.com/file.php"];

            NSURL *urlNew = [NSURL URLWithString:url];
            self.request = [NSMutableURLRequest requestWithURL:urlNew];
            [self.request setHTTPMethod:@"GET"];
            [self.request setAllHTTPHeaderFields:headers];

            [self waitForData:^(BOOL dataReceived) {
                if (dataReceived) {
                    [self waitForESN:^(BOOL esnFound) {
                        if (esnFound) {
                            VariableStore *globals = [VariableStore sharedInstance];
                            checkESNWithCallback(globals.user_esn, globals.sessionInfo, success, error);
                        }
                    }];
                }
            }];
        }
    }];
}

- (void)fillAppointmentData:(fillArray)compblock {

    VariableStore *globals = [VariableStore sharedInstance];

    NSDictionary *cookieProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                  @"ollie/", NSHTTPCookieDomain,
                                  @"\\", NSHTTPCookiePath,
                                  @"Cookie", NSHTTPCookieName,
                                  globals.sessionInfo, NSHTTPCookieValue,
                                  nil];
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    NSArray *cookieArray = [NSArray arrayWithObject:cookie];
    NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];

    NSMutableString *url = [[NSMutableString alloc] initWithString:@"https://company.com/file2.php?adb="];

    [url appendString:globals.chosenDate];
    [url appendString:@"&esn="];
    [url appendString:globals.user_esn];

    NSURL *urlNew = [NSURL URLWithString:url];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlNew];
    [request setHTTPMethod:@"GET"];
    [request setAllHTTPHeaderFields:headers];

    [self gettingData:^(NSData *myData, NSError *error) {
        if (myData != nil) {
            ParseXML *myParser = [[ParseXML alloc] initWithData:myData];

            [globals.appointmentData removeAllObjects];

            [globals.appointmentData addObjectsFromArray:myParser.items];
        }
    }];
}

- (void) gettingData:(getTheData) compblock {
    VariableStore *globals = [VariableStore sharedInstance];
    globals.got401 = nil;
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:self.request
                                        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                            if (error) {
                                                return;
                                            }

                                            if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
                                                NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];

                                                if (statusCode != 200) {
                                                    if (statusCode == 401) {
                                                        // Insert process for thumbprint and session cookie pull
                                                        NSFileManager *fileManagerThree = [NSFileManager defaultManager];
                                                        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
                                                        NSString *sessionPath = [documentsPath stringByAppendingPathComponent:@"session.txt"];
                                                        NSError *error;
                                                        BOOL success = [fileManagerThree removeItemAtPath:sessionPath error:&error];
                                                        if (success) {
                                                        } else {
                                                        }
                                                        globals.got401 = @"Error";
                                                    } else {
                                                        return;
                                                    }
                                                }
                                            }
                                            self.parseData = data;
                                        }];
    [task resume];
}

@end

If you only have 3 or 4 appointments worth of data stored locally then the answer is "whatever is easiest for you." 如果本地仅存储3或4个约会数据,那么答案是“最适合您的条件”。 It really doesn't matter. 真的没关系。 You could convert the data to morse code and save dots and dashes and then read that and it would still be small and fast enough. 您可以将数据转换为莫尔斯电码并保存点和破折号,然后读取该数据,它仍然足够小且足够快。

You can save the data to a plist, serialize it using NSCoding, save it as a SQLite database, or even write the XML and convert it back to an array on reading it (although the XML option is probably the slowest/least efficient.) 您可以将数据保存到plist,使用NSCoding进行序列化,将其保存为SQLite数据库,甚至可以编写XML并在读取数据时将其转换回数组(尽管XML选项可能是最慢/效率最低的)。

Core Data is very powerful (and very cool) but it also has a very steep learning curve. 核心数据非常强大(非常酷),但是学习曲线也非常陡峭。 I would not recommend it until you are comfortable working with iOS. 在您习惯使用iOS之前,我不建议您这样做。

If your application is timing out then there is probably something else wrong. 如果您的应用程序超时,则可能还有其他问题。 Edit your question to show the code for the problem area and perhaps we can help. 编辑您的问题以显示问题区域的代码,也许我们可以为您提供帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM