我们有一个iOS 9.2应用程序,在通过Xcode和本地Mac安装时运行良好。当我们通过MDM服务器安装此应用程序时,它会在第一次访问数据时崩溃。它正在退出,错误是“在10.00s之后无法进行场景更新。”
我在检查控制台输出时,似乎在requireLogin方法的成功过程之后挂起(在[self checkIntSession:self.sessionDetail]之后。
我们使用的是Novell的MDM而不是Apple版本。我创建了其他已安装并运行没有问题的应用程序。
我尝试过干净的构建和安装。它没有帮助。我在这里或其他地方找不到类似的问题。我不知道接下来要去哪里。任何帮助将不胜感激。
#import "Security.h"
#import "XMLTypeItem.h"
#import "ParseTypeXML.h"
#import "XMLPostSecurity.h"
#import "XMLSessionItem.h"
#import "FileSaving.h"
#import <LocalAuthentication/LocalAuthentication.h>
@implementation Security
- (NSString *)retrieveESN {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0];
NSString *fullPath = [documentsDirectoryPath stringByAppendingString:@"/session.txt"];
if ([fileManager fileExistsAtPath:fullPath]==YES) {
_finished = false;
[self readSession];
NSString *result = [self checkSession:_sessionDetail];
if ([result isEqualToString:@"Error"]) {
NSString *userESN = [self newFile];
if (self.getUserESN){
self.getUserESN(userESN);
}
return userESN;
} else {
return result;
}
} else {
_finished = false;
NSString *userESN = [self newFile];
return userESN;
}
}
- (NSString *)newFile {
[self requireLogin];
if (self.findUserESN) {
self.findUserESN(_passESN);
}
return _passESN;
}
- (void)requestSession {
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSString *url = @"https://company.com/loginfile";
NSMutableString *postText = [[NSMutableString alloc] init];
[postText appendString:idfv];
NSString *postBody = [NSString stringWithString:postText];
XMLPostSecurity *postAction = [[XMLPostSecurity alloc] init];
_sessionDetail = [postAction sendPostRequestToUrl:url withBody:postBody];
FileSaving *saver = [[FileSaving alloc] init];
[saver saveSession:self.sessionDetail];
}
-(NSString *)readSession {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0];
NSString *fullPath = [documentsDirectoryPath stringByAppendingString:@"/session.txt"];
if (self.fileExistsNow) {
self.fileExistsNow([fileManager fileExistsAtPath:fullPath]);
}
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];
_sessionDetail = [[NSString alloc] initWithData:dataBuffer encoding:(NSASCIIStringEncoding)];
return _sessionDetail;
}
-(void)readIntSession {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [directoryPaths objectAtIndex:0];
NSString *fullPath = [documentsDirectoryPath stringByAppendingString:@"/session.txt"];
if (self.fileExistsNow) {
self.fileExistsNow([fileManager fileExistsAtPath:fullPath]);
}
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];
_sessionDetail = [[NSString alloc] initWithData:dataBuffer encoding:(NSASCIIStringEncoding)];
}
-(NSString *)checkSession:(NSString *)sessionFound {
NSDictionary *cookieProperties = [NSDictionary dictionaryWithObjectsAndKeys:
@"ollie/", NSHTTPCookieDomain,
@"\\", NSHTTPCookiePath,
@"Cookie", NSHTTPCookieName,
sessionFound, 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];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlNew];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest: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;
}];
[task resume];
if (self.parseDataAvailable) {
self.parseDataAvailable(self.parseData);
}
ParseTypeXML *myParser = [[ParseTypeXML alloc] initWithData:self.parseData];
if ([myParser.esn count] == 0) {
return @"Error";
} else {
return myParser.esn[0];
}
}
-(void)checkIntSession:(NSString *)sessionFound {
NSDictionary *cookieProperties = [NSDictionary dictionaryWithObjectsAndKeys:
@"ollie/", NSHTTPCookieDomain,
@"\\", NSHTTPCookiePath,
@"Cookie", NSHTTPCookieName,
sessionFound, 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];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlNew];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest: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;
}];
[task resume];
if ( self.parseDataAvailable) {
self.parseDataAvailable(self.parseData);
}
ParseTypeXML *myParser = [[ParseTypeXML alloc] initWithData:self.parseData];
if ([myParser.esn count] == 0) {
_passESN = @"Error";
} else {
_passESN = myParser.esn[0];
}
}
- (void)requireLogin {
LAContext *context = [[LAContext alloc] init];
NSError *error = nil;
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
// Authenticate User
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:@"You must log in to the app."
reply:^(BOOL success, NSError * _Nullable error) {
if (success) {
self.finished = true;
if (self.touchIDWorks){
self.touchIDWorks(self.finished);
}
[self requestSession];
[self readIntSession];
[self checkIntSession:self.sessionDetail];
} else {
switch (error.code) {
case LAErrorAuthenticationFailed:
break;
case LAErrorUserCancel:
break;
case LAErrorUserFallback:
break;
default:
break;
}
}
}];
} else {
}
}
- (void)dataIsThere:(void (^)(NSData *foundData))finishBlock {
self.parseDataAvailable = finishBlock;
}
- (void)thumbOK:(void (^)(BOOL success))finishBlock {
self.touchIDWorks = finishBlock;
}
- (void)esnIsHere:(void (^)(NSString *newESN))finishBlock {
self.getUserESN = finishBlock;
}
- (void)esnIsReady:(void (^)(NSString *))finishBlock {
self.findUserESN = finishBlock;
}
- (void)fileReady:(void (^)(BOOL))finishBlock {
self.fileExistsNow = finishBlock;
}
从ViewController.m调用它:
- (IBAction)getESN:(id)sender {
Security *pulledESN = [[Security alloc] init];
self.gottenESN = [pulledESN retrieveESN];
self.responseLabel.text = self.gottenESN;
}
===稍后添加===
放入完成块并没有解决问题。完成requireLogin成功部分后,代码似乎仍然挂起。就像我需要回报一样。
答案 0 :(得分:1)
这条线对我来说太可怕了:
while ( self.parseData == NULL );
这可能是调试与发布版本问题。我可以想象一个发布版本优化self.parseData的读取,以便不检查其他线程是否已更新它。
我建议您以其他方式执行此操作 - 在这样的循环中进行轮询时,CPU会在等待时将CPU固定为100%。我建议把它写成与数据准备就绪时调用的完成块异步。