在我的应用程序中,我在NSDictionary中存储了大约6个不同的密钥,并将该字典存储为文件,以便将其发送给应用程序的其他用户。我的三个键是我作为字符串存储的数字:(例如)
NSString *altitudeData = [NSString stringWithFormat:%1.50f",_altitude];
[mutableDict setObject:altitudeData forKey:@"altitude"];
[mutableDict writeToFile:filePath atomically:YES];
我用一些相关的媒体文件将其压缩并发送。
通常一切正常。应用程序接收压缩文件,解压缩,读取NSDictionary文件(基本上是XML)并根据刚收到的信息创建对象。
然而,事情并不能正常发挥作用。这个问题让我特别困惑,因为我有相同的确切文件发送到我的应用程序和我的电脑。我存储为字符串的数字键(如上面的示例)在我的应用程序读取的文件中更改为0.00000 ..........
<key>altitude</key>
<string>0.00000000000000000000000000000000000000000000000000</string>
我在我的计算机上打开NSDictionary作为XML,我可以清楚地看到它们是正确的,就像我在导出时一样。
<key>altitude</key>
<string>27.19356918334960937500000000000000000000000000000000</string>
我已多次确认这些文件确实是同一个文件,其他一切都是一样的。我还尝试删除我的应用并重新运行,以确保我不会意外地读取错误的文件。这些领域如何以及为何变换?我能做些什么来阻止它吗?
编辑:回复有关我如何压缩文件的请求 我实际上使用了一些我从github导入的代码来实现这个目的
//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]方法
+(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
;
}
答案 0 :(得分:1)
我希望答案是深刻的,但不幸的是,原因是懒惰编程的结果。我的应用中有两个地方使用文件重新创建ObjectItem
。在一个我从文档文件夹中的信息中重新创建对象,在另一个中我从temp中的信息重新创建。
我用来从文件中重新创建对象的方法(我上面已经提到)+(ObjectItem*)retrieveFromName:
总是在Document文件夹中查找。当它没有在那里看到文件时,我的应用程序将重新创建没有高度/坐标的ObjectItem
,并在Document文件夹中生成相应的文件。