Ios 通过电子邮件发送的NSDictionary文件与应用程序中的相同文件不同
在我的应用程序中,我在NSDictionary中存储了大约6个不同的键,并将该字典存储为一个文件,以便将其发送给应用程序的其他用户。我的三个键是存储为字符串的数字:(例如) 我用一些相关的媒体文件将其压缩并发送出去 通常一切正常。应用程序接收压缩文件,将其解压,读取NSDictionary文件(基本上是XML),并根据刚刚收到的信息创建一个对象 然而,事情并不总是正确的。这个问题让我特别困惑,因为我的应用程序和电脑都收到了相同的文件。在我的应用程序读取的文件中,作为字符串存储的数字键(如上面的示例)被更改为0.00000Ios 通过电子邮件发送的NSDictionary文件与应用程序中的相同文件不同,ios,objective-c,xml,nsdictionary,Ios,Objective C,Xml,Nsdictionary,在我的应用程序中,我在NSDictionary中存储了大约6个不同的键,并将该字典存储为一个文件,以便将其发送给应用程序的其他用户。我的三个键是存储为字符串的数字:(例如) 我用一些相关的媒体文件将其压缩并发送出去 通常一切正常。应用程序接收压缩文件,将其解压,读取NSDictionary文件(基本上是XML),并根据刚刚收到的信息创建一个对象 然而,事情并不总是正确的。这个问题让我特别困惑,因为我的应用程序和电脑都收到了相同的文件。在我的应用程序读取的文件中,作为字符串存储的数字键(如上面的示
<key>altitude</key>
<string>0.00000000000000000000000000000000000000000000000000</string>
要解压缩:
NSData *fileAsData = [NSData dataWithContentsOfURL:file];
NSString *urlAsString = file.absoluteString;
NSArray *brokenFile = [urlAsString componentsSeparatedByString:@"/"];
NSString *fileName = [brokenFile lastObject];
NSString *buildPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"constructing"];
createDirectory(buildPath);
NSString *filePath = [buildPath stringByAppendingPathComponent:fileName];
[fileAsData writeToFile:filePath atomically:NO];
////HERE IS THE CLASS IMPORTED FROM github
bool upziped = [SSZipArchive unzipFileAtPath:filePath toDestination:buildPath];
if (upziped) {
NSLog(@"unzipped");
}
else {
NSLog(@"not unzipped");
}
NSArray* buildDirectory = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:buildPath error:NULL];
//import NSDictionary file
ObjectItem *object = nil; /* This is the object I'm re-creating with my file*/
for (NSString*s in buildDirectory) {
NSLog(@"files here: %@",s);
if ([s rangeOfString:@".xml"].location != NSNotFound) {
NSString *name = [[s componentsSeparatedByString:@"."]firstObject];
object = [ObjectItem retrieveFromName:name];
break;
}
}
//import image
UIImage *image;
for (NSString *media in buildDirectory) {
if ([media rangeOfString:@".png"].location != NSNotFound) {
NSString *imageFilePath = [buildPath stringByAppendingPathComponent:media];
image = [[UIImage alloc]initWithContentsOfFile:imageFilePath];
[object importImage:image];
break;
}
}
//import video
for (NSString *media in buildDirectory) {
if ([media rangeOfString:@".MOV"].location != NSNotFound) {
NSString *videoFilePath = [buildPath stringByAppendingPathComponent:media];
[object importVideo:videoFilePath];
break;
}
}
//import audio
NSString *audioExt = [NSString stringWithFormat:@".%@",AUDIO_EXT];
for (NSString *media in buildDirectory) {
if ([media rangeOfString:audioExt].location != NSNotFound) {
NSString *audioFilePath = [buildPath stringByAppendingPathComponent:media];
[object importAudio:audioFilePath];
break;
}
}
[object save];
此外,如果[ObjectItem retrieveFromName]方法在这里有帮助
+(ObjectItem
*)retrieveFromName:(NSString*)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *subDirectory = [documentsDirectory stringByAppendingPathComponent:@"ObjectItems"];
createDirectory(subDirectory);
NSString *filePath = [subDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.xml",name]];
NSString *file = [NSString stringWithContentsOfFile:filePath encoding:NSASCIIStringEncoding error:nil];
NSLog(@"file contents:\n%@\n",file);
file = nil;
NSDictionary *myDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
for (NSString *s in myDict) {
NSLog(@"key \"%@\" has value: %@",s,[myDict objectForKey:s]);
}
double lat = [[myDict objectForKey:@"latitude"]doubleValue];
double lon = [[myDict objectForKey:@"longitude"]doubleValue];
double alt = [[myDict objectForKey:@"altitude"]doubleValue];
CLLocation *loc = [[CLLocation alloc]initWithCoordinate:CLLocationCoordinate2DMake(lat, lon)
altitude:alt
horizontalAccuracy:kCLLocationAccuracyBestForNavigation
verticalAccuracy:kCLLocationAccuracyBestForNavigation
timestamp:[NSDate date]];
UIImage *im = nil;
NSString *vid = nil;
NSString *aud = nil;
ObjectItem
*object
= [[ObjectItem
alloc]initWithName:name location:loc];
NSString *key = [myDict objectForKey:@"image"];
if (key != nil) {
im = [UIImage imageWithContentsOfFile:key];
[object
importImage:[im copy]];
}
key = nil;
key = [myDict objectForKey:@"video"];
if (key != nil) {
vid = [NSString stringWithString:key];
[object
importVideo:[vid copy]];
}
key = nil;
key = [myDict objectForKey:@"audio"];
if (key != nil) {
aud = [NSString stringWithString:key];
[object
importAudio:[aud copy]];
}
paths = nil;
documentsDirectory = subDirectory = filePath = nil;
im = nil;
vid = nil;
aud = nil;
myDict = nil;
key = nil;
return object
;
}
我希望答案是深刻的,但不幸的是,原因是懒惰编程的结果。在我的应用程序中有两个地方,我可以使用文件重新创建我的
ObjectItem
。其中一个是从文档文件夹中的信息重新创建对象,另一个是从临时文件夹中的信息重新创建对象
我用来从文件中重新创建对象的方法(我在上面有)
+(ObjectItem*)retrieveFromName:
总是在文档文件夹中查找。当它没有看到那里的文件时,我的应用程序将重新创建没有高度/坐标的ObjectItem
,并在文档文件夹中生成相应的文件。旁注-为什么要保留50个小数位?一个double
只适用于大约13或14个有效数字。你说得对。我想这有点过分了。我遇到了一些由于精度不足而导致的错误,我可能有点补偿过度了。我们不知道你从哪里得到的高度。我们需要看更多的代码。这真的重要吗?据我所知,这些值是正确写入的,并在台式机上进行了验证@dev574,您是否100%确定值写入正确?对他们来说,事后更改是相当神秘的。我看不出有什么办法可以帮助他们,只是说文件中的值不会自动更改。要弄清这一点,你所说的“我把它压缩并发送到我的应用程序”和“我将相同的文件发送到我的计算机”都是什么意思。请用代码(和NSLog输出)重述这些句子。其他评论员提示您发布不相关的代码。请随意取下它。(换句话说,请添加这样的内容:在发送之前,这里是NSLog输出。这里是我压缩和发送的方式,这里是接收端不同的日志输出)。
//first locate temp directory
NSString *tmpDirectory = NSTemporaryDirectory();
NSMutableString *fileNameOfZip = [NSMutableString stringWithFormat:@"%@.zip",_name];
[fileNameOfZip replaceOccurrencesOfString:@" " withString:@"_" options:NSBackwardsSearch range:NSMakeRange(0, fileNameOfZip.length)];
NSString *zipFilePath = [tmpDirectory stringByAppendingPathComponent:
fileNameOfZip];
//then find all files related to zipping
NSString *mainFilePath = [FILE_DIR stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.xml",_name]];
NSString *imageFilePath = [self saveImages];
NSString *videoFilePath = [self saveVideo];
NSString *audioFilePath = [self saveAudio];
NSMutableArray *filesToAdd = [[NSMutableArray alloc]initWithObjects: nil];
[filesToAdd addObject:mainFilePath];
[filesToAdd addObject:imageFilePath];
[filesToAdd addObject:videoFilePath];
[filesToAdd addObject:audioFilePath];
////HERE IS THE CLASS IMPORTED FROM github
bool successful_zip = [SSZipArchive createZipFileAtPath:zipFilePath withFilesAtPaths:filesToAdd];
NSData *fileAsData = [NSData dataWithContentsOfURL:file];
NSString *urlAsString = file.absoluteString;
NSArray *brokenFile = [urlAsString componentsSeparatedByString:@"/"];
NSString *fileName = [brokenFile lastObject];
NSString *buildPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"constructing"];
createDirectory(buildPath);
NSString *filePath = [buildPath stringByAppendingPathComponent:fileName];
[fileAsData writeToFile:filePath atomically:NO];
////HERE IS THE CLASS IMPORTED FROM github
bool upziped = [SSZipArchive unzipFileAtPath:filePath toDestination:buildPath];
if (upziped) {
NSLog(@"unzipped");
}
else {
NSLog(@"not unzipped");
}
NSArray* buildDirectory = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:buildPath error:NULL];
//import NSDictionary file
ObjectItem *object = nil; /* This is the object I'm re-creating with my file*/
for (NSString*s in buildDirectory) {
NSLog(@"files here: %@",s);
if ([s rangeOfString:@".xml"].location != NSNotFound) {
NSString *name = [[s componentsSeparatedByString:@"."]firstObject];
object = [ObjectItem retrieveFromName:name];
break;
}
}
//import image
UIImage *image;
for (NSString *media in buildDirectory) {
if ([media rangeOfString:@".png"].location != NSNotFound) {
NSString *imageFilePath = [buildPath stringByAppendingPathComponent:media];
image = [[UIImage alloc]initWithContentsOfFile:imageFilePath];
[object importImage:image];
break;
}
}
//import video
for (NSString *media in buildDirectory) {
if ([media rangeOfString:@".MOV"].location != NSNotFound) {
NSString *videoFilePath = [buildPath stringByAppendingPathComponent:media];
[object importVideo:videoFilePath];
break;
}
}
//import audio
NSString *audioExt = [NSString stringWithFormat:@".%@",AUDIO_EXT];
for (NSString *media in buildDirectory) {
if ([media rangeOfString:audioExt].location != NSNotFound) {
NSString *audioFilePath = [buildPath stringByAppendingPathComponent:media];
[object importAudio:audioFilePath];
break;
}
}
[object save];
+(ObjectItem
*)retrieveFromName:(NSString*)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *subDirectory = [documentsDirectory stringByAppendingPathComponent:@"ObjectItems"];
createDirectory(subDirectory);
NSString *filePath = [subDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.xml",name]];
NSString *file = [NSString stringWithContentsOfFile:filePath encoding:NSASCIIStringEncoding error:nil];
NSLog(@"file contents:\n%@\n",file);
file = nil;
NSDictionary *myDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
for (NSString *s in myDict) {
NSLog(@"key \"%@\" has value: %@",s,[myDict objectForKey:s]);
}
double lat = [[myDict objectForKey:@"latitude"]doubleValue];
double lon = [[myDict objectForKey:@"longitude"]doubleValue];
double alt = [[myDict objectForKey:@"altitude"]doubleValue];
CLLocation *loc = [[CLLocation alloc]initWithCoordinate:CLLocationCoordinate2DMake(lat, lon)
altitude:alt
horizontalAccuracy:kCLLocationAccuracyBestForNavigation
verticalAccuracy:kCLLocationAccuracyBestForNavigation
timestamp:[NSDate date]];
UIImage *im = nil;
NSString *vid = nil;
NSString *aud = nil;
ObjectItem
*object
= [[ObjectItem
alloc]initWithName:name location:loc];
NSString *key = [myDict objectForKey:@"image"];
if (key != nil) {
im = [UIImage imageWithContentsOfFile:key];
[object
importImage:[im copy]];
}
key = nil;
key = [myDict objectForKey:@"video"];
if (key != nil) {
vid = [NSString stringWithString:key];
[object
importVideo:[vid copy]];
}
key = nil;
key = [myDict objectForKey:@"audio"];
if (key != nil) {
aud = [NSString stringWithString:key];
[object
importAudio:[aud copy]];
}
paths = nil;
documentsDirectory = subDirectory = filePath = nil;
im = nil;
vid = nil;
aud = nil;
myDict = nil;
key = nil;
return object
;
}