使用OS X沙箱写多个文件 [英] Write multiple files using OS X sandbox

查看:156
本文介绍了使用OS X沙箱写多个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个OS X沙盒应用程序。它接收@ 3x和@ 2x图像文件,并将其转换为较低分辨率的图像。我通过将文件拖动到应用程序窗口或使用NSOpenPanel选择的目录来获取图像URL。



一旦图像被拖动或文件夹被选择,我运行一个for循环并使用此方法调整每个图像的大小

   - (BOOL)writeImage:(NSImage *)image toFile: (NSString *)file withRepresentation:(NSString *)extension {

CGImageRef cgRef = [image CGImageForProposedRect:NULL
context:nil
hints:nil];
NSBitmapImageRep * newRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
[newRep setSize:[image size]];
NSData * pngData = [newRep representationUsingType:[self getRepresentationType:extension] properties:nil];
return [pngData writeToFile:[file stringByAppendingString:[NSString stringWithFormat:@。%@,extension]] atomically:YES];

这会中断沙盒模型。我读过我应该使用NSSavePanel,但这将要求我为每个保存的图像指定最终的文件路径/文件名,这会破坏用户体验。



有没有办法请求沙盒应用程序允许写入某个目录,而不是请求写入每个文件的权限?

解决方案



您已经知道如何使用 NSOpenPanel 允许用户选择目录 - 或使用NSOpenPanel选择的目录。当用户执行此操作时,您将获得该目录的读/写权限,因此您可以读取一个文件 name@3x.ext ,并写入一个名为 name@2x.ext



现在除了能够使用 NSOpenPanel 选择目录之外,还可以:


  1. 指定委托方法以确定应启用哪些项目供用户选择,以及确定用户选择的项目是否可接受; p>


  2. 设置当 NSOpenPanel 对话框打开时首次显示的目录;和 NSOpenPanel 对话框中


  3. 设置提示消息和按钮标签。 >

结合这些功能,您可以提出一个对话框,要求用户确认访问特定目录:


  1. 将提示设置为请确认访问目录;


  2. 将打开按钮上的标签设置为类似确认的内容;


  3. 将初始目录设置为你所在的目录;和


  4. 使用委托方法仅允许用户选择要取消的目录。




    1. 捆绑,例如 MyConfirmDirectoryPanel



      现在,当用户向您提供一个文件时:


      1. 确定该文件的目录

        b $ b
      2. 使用 access()系统调用检查是否有对目录的写访问权限 - 参见Unix手册的第2节在Xcode的文档中搜索 access )。


      3. 如果您没有访问权限,请使用 MyConfirmDirectoryPanel


      4. 您现在对该目录拥有写入权限,请继续创建您的缩放图像文件


      您以这种方式获得的访问将持续到您的应用程序的剩余执行;因此,如果,例如,您的用户然后选择在同一目录中的另一个文件,您不必再次请求权限。如果你想保留你的应用程序的执行之间的访问,你也可以这样做。您可以使用安全范围书签查找这些文档。使用该机制,您可以创建已保存书签的缓存 - 将它们存储在您的用户默认值中 - 您可以根据需要激活,重新获得对用户以前授予您的目录的访问权限。如果你这样做的时间,你必须明确要求用户的权限将减少,你的用户将获得他们所期望的UI体验 - 拖动一个文件,在同一目录下创建它的大小已调整大小。



      HTH


      I'm writing an OS X sandboxed application. It recieves @3x and @2x image files and transforms them into lower resolution images. I'm getting the image URLs by either the files being dragged into the app window or a directory being chosen using NSOpenPanel.

      Once the images are dragged or the folder is selected, I run a for loop and resize each image using this method

      -(BOOL)writeImage:(NSImage*)image toFile:(NSString*)file withRepresentation:(NSString*)extension{
      
      CGImageRef cgRef = [image CGImageForProposedRect:NULL
                                               context:nil
                                                 hints:nil];
      NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithCGImage:cgRef];
      [newRep setSize:[image size]];
      NSData *pngData = [newRep representationUsingType:[self getRepresentationType:extension] properties:nil];
      return [pngData writeToFile:[file stringByAppendingString:[NSString stringWithFormat:@".%@",extension]] atomically:YES];
      

      This breaks the sandbox model. I've read I should be using NSSavePanel, but this would require me to specify the final filepath/filename for each of the saved images, which ruins the user experience.

      Is there any way to ask the sandboxed app permision to write to certain directory instead of asking permission to write each file?

      解决方案

      Yes, you can easily ask for permission to write to a certain directory.

      You already know how to use NSOpenPanel to allow the user to select a directory - "or a directory being chosen using NSOpenPanel". When the user does that you get read/write permission on the directory, so you can read a file name@3x.ext and write one named name@2x.ext etc.

      Now in addition to being able to use NSOpenPanel to select a directory you can also:

      1. specify delegate methods to determine which items should be enabled for the user to select, and to determine if a user selected item is acceptable;

      2. set the directory which is first displayed when the NSOpenPanel dialog is opened; and

      3. set prompt messages and button labels in the NSOpenPanel dialog.

      Combining these features you can present a dialog which asks the user to confirm access to a specific directory:

      1. set the prompt to something like "Please confirm access to directory";

      2. set the label on the "Open" button to something like "Confirm";

      3. set the initial directory to the parent of the directory you are after; and

      4. use the delegate methods to only allow the user to either choose the directory to cancel.

      Bundle that up as, say, MyConfirmDirectoryPanel.

      Now when the user presents you with a file:

      1. Determine the directory of that file

      2. Check whether you have write access to the directory using the access() system call - see section 2 of the "Unix" manual (just search for access in Xcode's documentation). If you have write access go to (4).

      3. If you don't have access use your MyConfirmDirectoryPanel to have the user select the directory, thus granting you access.

      4. You now have write permission on the directory, go ahead and create your scaled image file.

      The access you gain in this way will last for the remaining execution of your app; so if, for example, your user then selects another file in the same directory you won't have to ask for permission again. If you want to preserve the access between executions of your app you can do that as well. You this this using a security scoped bookmark, look up the documentation of those. Using that mechanism you can create a cache of saved bookmarks - storing them say in your user defaults - which you can activate as needed to regain access to directories previously granted to you by the user. If you do this over time the number of times you have to explicitly ask the user for permission will dwindle and your user will get the UI experience they expect - drag a file, resized imaged created next to it in same directory.

      HTH

      这篇关于使用OS X沙箱写多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆