将文件写入iOS App Bundle,还是显示2个目录的内容?
在我现有的应用中,我有大约450个非常小的PDF文件,这些文件是歌曲的歌词。它们都存储在称为(适当)“ thepdfs”的目录中。不利的一面是,每次我想添加一组新的歌词时,我都必须发布该应用程序的更新。我想做的是使用Parse Server之类的东西指向在线存储的PDF,并允许用户选择这些PDF并将其添加到其现有列表中。
但是,我认为这是不可能的,还是允许我乘坐外部PDF并将其写入名为“ thepdfs”的目录中?如果不允许这样做,那么所有歌曲都在一个列表中的方式是什么?我知道我可以将它们下载到该应用程序的文档文件夹中,但是后来我在多个位置有歌曲,并且在一个tableview中访问它们可能会更加困难。我想在该应用程序的首次启动时,我可以将所有PDF从捆绑部分中的所有PDF复制到文档目录中,然后从中搜索它?
我知道我有很多选择,我很好奇我是否缺少东西。 更新 因此,我正在尝试做出第一个将PDF留在原处的选择,并制作一个将每个歌曲名称的项目以及文件系统中的位置。然后,当添加新歌时,它也会做同样的事情,无论它们在哪里,我都可以从PLIST文件中阅读以获取所有歌曲并可以打开它们。我现在的问题是设置初始的PLIST,以及我为每个后续添加所做的工作背后的逻辑。我得到的问题是
NSDictionary initWithObjects:forKeys:]: count of objects (0) differs from count of keys (1)'
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"mastersonglist.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path]) {
path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"mastersonglist.plist"] ];
}
NSError *error = nil;
NSMutableDictionary *data;
if ([fileManager fileExistsAtPath: path]) {
data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
}
else {
// If the file doesn’t exist, create an empty dictionary
data = [[NSMutableDictionary alloc] init];
}
NSBundle *bundle = [NSBundle mainBundle];
self.files = [bundle pathsForResourcesOfType:@"pdf" inDirectory:@"thepdfpowerpoints"];
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
for (NSString *path in self.files) {
[names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
}
for (NSString *test in names) {
// [data setObject:names forKey:@"thename"];
// [data writeToFile:path atomically:YES];
NSDictionary *innerDict;
NSLog(@"NAMES%@", names);
innerDict = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects: names, path, nil]
forKeys:[NSArray arrayWithObjects:@"Names", @"Path", nil]];
NSLog(@"DICT%@", innerDict);
NSMutableDictionary *plistdictionary = [[NSMutableDictionary alloc]initWithContentsOfFile:path];
NSMutableArray *notes=[plistdictionary objectForKey:@"Questions"];
//NSLog(@"QUESTION %@", innerDict);
[notes addObject:innerDict];
NSLog(@"NOTES %@", notes);
NSDictionary *outerDict = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects: notes, nil]
forKeys:[NSArray arrayWithObjects:@"Questions", nil]];
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)outerDict
format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
[plist writeToFile:path atomically:YES];
}
In my existing app, I have about 450 very small PDF files that are lyrics to songs. They are all stored in a directory called (appropriately) "ThePDFs". The downside with this is that every time I want to add a new set of lyrics, I have to release an update to the app. What I'd love to do is use something like the Parse server to point toward PDFs stored online, and allow the user to select those and add them to their existing list.
However, I don't think it is possible or allowed for me to take an outside PDF and write them into that directory called "ThePDFs"? If it's not allowed, what would be a good way to accomplish this, in such a way that all the songs are in one list? I know I could download them into a documents folder for the app, but then I have songs in multiple locations, and accessing them all in one tableview might be more difficult. I suppose at first launch of the app, I could have all the PDFs copy from the bundled section into the documents directory, and search to it from that?
I know I have a lot of options, I'm just curious if there's something I'm missing.
UPDATE
So, I'm trying to do the first option of leaving PDFs where they are, and make a PLIST that would have an item with each song's name, along with the location for where it is in the file system. Then, when new songs are added, it would do the same, and I could read from the PLIST file to get all songs and be able to open them, no matter where they are. My issue right now is getting the initial PLIST set up, and the logic behind what I would do for each subsequent addition. The issue I get is
NSDictionary initWithObjects:forKeys:]: count of objects (0) differs from count of keys (1)'
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"mastersonglist.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path]) {
path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"mastersonglist.plist"] ];
}
NSError *error = nil;
NSMutableDictionary *data;
if ([fileManager fileExistsAtPath: path]) {
data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
}
else {
// If the file doesn’t exist, create an empty dictionary
data = [[NSMutableDictionary alloc] init];
}
NSBundle *bundle = [NSBundle mainBundle];
self.files = [bundle pathsForResourcesOfType:@"pdf" inDirectory:@"thepdfpowerpoints"];
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
for (NSString *path in self.files) {
[names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
}
for (NSString *test in names) {
// [data setObject:names forKey:@"thename"];
// [data writeToFile:path atomically:YES];
NSDictionary *innerDict;
NSLog(@"NAMES%@", names);
innerDict = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects: names, path, nil]
forKeys:[NSArray arrayWithObjects:@"Names", @"Path", nil]];
NSLog(@"DICT%@", innerDict);
NSMutableDictionary *plistdictionary = [[NSMutableDictionary alloc]initWithContentsOfFile:path];
NSMutableArray *notes=[plistdictionary objectForKey:@"Questions"];
//NSLog(@"QUESTION %@", innerDict);
[notes addObject:innerDict];
NSLog(@"NOTES %@", notes);
NSDictionary *outerDict = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects: notes, nil]
forKeys:[NSArray arrayWithObjects:@"Questions", nil]];
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)outerDict
format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
[plist writeToFile:path atomically:YES];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您是正确的,您不能在运行时将文件添加到App Bundle。
因此,根据您要向用户提供的功能,各种方法可以解决此问题。
首先,您可以:
从两个位置生成数据列表以在单个表中显示一个非常直的 - 前进且不在整个复杂任务。
其次,您可以:
您只需要在一个位置管理文件即可。
第三,您可以:
编辑< / strong>
您实际上不需要知道文件位置...
我不知道您拥有哪些信息与每个PDF文件相关联,为了简化,让我们假设您正在显示PDF文件名列表(没有其他数据)。
总体想法可能是:
是否存在下载spath/filename.pdf
是否存在?如果您有某种数据文件 - .plist,csv,json等,
是否存在下载spath/filename.pdf
是否存在?无需跟踪数据中的文件位置 - 只需在要加载时找到它即可。
First, you're correct, you cannot add files to the app bundle at run-time.
So, various ways to approach this, depending on what functionality you want to provide to the user.
First, you could:
generating a data list from both locations to display in a single table would really be a pretty straight-forward and not-at-all complex task.
Second, you could:
Now you only need to manage the files in one location.
Third, you could:
Edit
You don't really need to know the file locations...
I don't know what information you have associated with each PDF file, so, to simplify, let's assume you're displaying a list of PDF file names (no other data).
The general idea could be:
downloadsPath/filename.pdf
exist?Same principal if you have some sort of data file - .plist, csv, json, whatever - that would have maybe filename, song title, artist, date, etc.
downloadsPath/filename.pdf
exist?No need to track the file location in your data -- just find it when you want to load it.