将文件写入iOS App Bundle,还是显示2个目录的内容?

发布于 2025-02-04 02:11:54 字数 3608 浏览 3 评论 0原文

在我现有的应用中,我有大约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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哭泣的笑容 2025-02-11 02:11:54

首先,您是正确的,您不能在运行时将文件添加到App Bundle。

因此,根据您要向用户提供的功能,各种方法可以解决此问题。

首先,您可以:

  • 在您的应用程序捆绑包中包含现有的PDF
  • 在启动时检查新的PDF的远程服务器,将
  • 新的PDF下载到本地应用程序文件夹中,

从两个位置生成数据列表以在单个表中显示一个非常直的 - 前进且不在整个复杂任务。

其次,您可以:

  • 在您的应用程序包中包含 no pdfs
  • 在启动时检查远程服务器以获取新的PDF(在第一次启动时,它们都是新的)
  • 下载PDFS(在背景线程上,当然是)现在进入本地应用程序夹,

您只需要在一个位置管理文件即可。

第三,您可以:

  • 在您的应用程序包中包含 no pdfs
  • 在启动时查看可用PDFS 的远程服务器,
  • 时,请访问pdfs pdfs按点播。
  • 当用户选择选项 在本地“缓存”它们 - 因此,仅当尚未选择 /下载PDF

编辑< / strong>

您实际上不需要知道文件位置...

我不知道您拥有哪些信息与每个PDF文件相关联,为了简化,让我们假设您正在显示PDF文件名列表(没有其他数据)。

总体想法可能是:

  • 在捆绑包中获取PDF文件列表
  • ,请附加下载文件夹中的PDF文件
  • 列表
    • 文件是否存在下载spath/filename.pdf是否存在?
      • 是吗?加载
      • 不?从捆绑装加载

如果您有某种数据文件 - .plist,csv,json等,

  • ,这可能具有文件名,歌曲标题,艺术家,日期等。加载捆绑包中包含的PDF文件的数据
  • 在下载文件夹中附加PDF文件的数据
  • ,对完整列表按字母顺序
  • 选择一首歌
    • 文件是否存在下载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:

  • include the existing PDFs in your app bundle
  • check a remote server for new PDFs on launch
  • download the new PDFs into a local app folder

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:

  • include NO PDFs in your app bundle
  • check a remote server for new PDFs on launch (on first launch they'd all be new)
  • download the PDFs (on a background thread, of course) into a local app folder

Now you only need to manage the files in one location.

Third, you could:

  • include NO PDFs in your app bundle
  • check a remote server for the list of available PDFs on launch
  • retrieve the PDFs on-demand when the user selects them
  • optionally "cache" them locally - so only retrieve if the PDF has not already been selected / downloaded

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:

  • get the list of PDF files in the bundle
  • append the list of PDF files in the downloads folder
  • sort the full list alphabetically
  • user selects a PDF
    • does file downloadsPath/filename.pdf exist?
      • Yes? load it
      • No? load it from bundle

Same principal if you have some sort of data file - .plist, csv, json, whatever - that would have maybe filename, song title, artist, date, etc.

  • load the data for the PDF files included in the bundle
  • append the data for the PDF files in the downloads folder
  • sort the full list alphabetically
  • user selects a song
    • does file downloadsPath/filename.pdf exist?
      • Yes? load it
      • No? load it from bundle

No need to track the file location in your data -- just find it when you want to load it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文