How do to identify that a file is a package? - objective-c

I have used NSDirectoryEnumerator to enumerate files in a Cocoa App (OSX). I am able to identify many properties of files e.g that a file is a directory or not, its creation date,modification date etc using NSURL File Property Keys. What I am not able to identify is that whether a file is a package or not ? I have gone through every bit of NSURL,NSFileManager reference but I have not been able to find a way. Am I missing something ?
I have also seen that for a file that is a package NSURLIsDirectoryKey returns true. But in my case I still want to categorise directories and packages separately.

I found the method in NSWorkspace class. wonder why it was not included in NSURL File Property Keys
- (BOOL)isFilePackageAtPath:(NSString *)fullPath
Return Value
YES if the path identifies a file package; otherwise, NO if the path does not exist, is not a directory, or is not a file package.

Related

Nextcloud in which source file is file uploading handled

I am going to make an app. But i am stuck in one issue. I am unable to find in which file of nextcloud, the codes are available which uploads file.
i want to find the file in which file uploading codes are situated.
I am going to make an app which will make a duplicate of uploaded file and will save in same directory with slightly changed name.
The public API for handling files lives in the \OCP\Files namespace, the implementation is in the \OC\Files namespace (https://github.com/nextcloud/server/tree/master/lib/private/Files).
Rather than modifying this code you should use the hooks functionality (never use classes or functions in the \OC\* namespace!): https://docs.nextcloud.com/server/12/developer_manual/app/hooks.html. This way you can execute your own code when a file is created or updated etc.
I guess you need the postWrite hook. Some sample code (untested):
\OC::$server->getRootFolder()->listen('\OC\Files', 'postWrite', function(\OCP\Files\Node $node) {
$node->copy('my/path');
});

How to access the location of the changelog file from custom task in Liquibase

I need to access the location of the change log file so that I can get the URL of other files that are in the same directory from a custom task.
The Change interface has a setter for the ChangeSet object which can be used to get the change log file, but the CustomChangeTask interface does not have this method.
From my understanding I need to use CustomChangeTask as my task does not generate SQL.
This is my question. I have decided to implement AbstractChange. It works just fine doing that and returning an empty array of SqlStatements.

Objective C - How to determine if a folder is a package?

App Packages are basically folders and you can read their contents just like any folders. I understood this.
My question is:
If I have a folder called folderA which has files and a package called PackageA which has files, how can I programmatically tell what is a normal folder and what is a package ?
In my application I need to exclude any packages but process any normal folders.
Any advise would be appreciated.
I have tried to check via NSBundle but both normal folder as well as package folder is an NSBundle. I was hoping one is not. I am sure there is a property that will tell me that?
I solved it as:
NSNumber *isPackage;
NSError *error = nil;
[filePath getResourceValue:&isPackage forKey:NSURLIsPackageKey error:&error];
if( [isPackage integerValue] == 1)
{
// treat as package
}
There are multiple ways to do this, the "modern" way is to use NSURL's getResourceValue:forKey:error: method (or one of its siblings). The key for determining whether the NSURL instance references a package is NSURLIsPackageKey.

Resource Files in CF - Not Embedded

I have a PPC2003 project in VS2005. I have added a resource file (SomeResources.resx) to the project. I can access the test string I have in the file by using My.Resources.SomeResources.MyTestString (I am using the default Custom Tool Name that VS provides).
When the Build Action property of the is set to Embedded Resource, the application references the MyTestString successfully.
But I do not want to embed the file, so that it's string values can be modified after it has been deployed/installed.
I, therefore, changed the Build Action to Content, so that the file gets copied out to the device for potential future manipulation. When I call MyTestString I get the following error:
MissingManifestResourceException Stack Trace: at System.Resources.ResourceManager.InternalGetResourceSet() at System.Resources.ResourceManager.InternalGetResourceSet() at System.Resources.ResourceManager.InternalGetResourceSet() at System.Resources.ResourceManager.GetString() at MyApp.My.Resources.SomeResources.get_MyTestString() at MyApp.fMain.fMain_Load() at System.Windows.Forms.Form.OnLoad() at System.Windows.Forms.Form._SetVisibleNotify() at System.Windows.Forms.Control.set_Visible() at System.Windows.Forms.Application.Run() at MyApp.fMain.Main()
As the file is not embedded, do I maybe need to manually load it first? If so, how? Any other ideas? Is it not possible to do what I'm after achieving and should I just create my own XML file/reader?
Resources (resx files) are specifically designed to be compiled into the application. If you want it to be an editable content file on the target, then you have to approach it differently and use something like an XML file and wrap that with accessors (akin to the Configuration namespace stuff in the full framework).

App Sandbox: document-scoped bookmark not resolving; not returning any error

I'm sandboxing my app, and trying to allow for import/export of multiple files, using an XML file to refer to them. To allow my app (or another sandboxed app) access to the files listed in the XML, I'm also including a serialized security-scoped bookmark. I'm serializing it as described in this answer, and my unit tests (which are not sandboxed) write and read the XML data without issue. When my app resolves the bookmark, the NSURL returned is nil, as is the NSError reference. Since I don't believe that should be the case, why is it happening? I can work around it by prompting the user to select a file/directory with an NSOpenPanel, but I'd still like to get the bookmarks to work as they should.
Reproduced in a test project
To reproduce at home, create a new Cocoa app in Xcode, and use the following Gist for the files in the project: https://gist.github.com/2582589 (updated with a proper next-view loop)
Then, follow Apple's instructions to code-sign the project. You reproduce the problem (which I submitted to Apple as rdar://11369377) by clicking the buttons in sequence. You pick any file on disk (outside the app's container), then an XML to export to, and then the same XML to import.
Hopefully you guys will be able to help me figure out what I'm doing wrong. Either I'm doing something wrong and the framework is erroneously keeping to itself, or I'm doing it right and it's totally broken. I try not to blame the framework, so which is it? Or is there another possibility?
Sample Code
Exporting the XML to docURL:
// After the user picks an XML (docURL) destination with NSSavePanel
[targetURL startAccessingSecurityScopedResource];
NSData *bookmark = [targetURL bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope
includingResourceValuesForKeys:nil
relativeToURL:docURL
error:&error];
[targetURL stopAccessingSecurityScopedResource];
Importing the XML from docURL:
// After the user selected the XML (docURL) from an NSOpenPanel
NSURL *result = [NSURL URLByResolvingBookmarkData:bookmarkData
options:NSURLBookmarkResolutionWithSecurityScope
relativeToURL:docURL
bookmarkDataIsStale:nil
error:&error];
I tried surrounding this call with[docURL ..AccessingSecurityScopedResource], which didn't make a difference (as expected, since the docURL is already within scope after having been selected in the Open Panel
Also, I specify the following in my app.entitlements file:
com.apple.security.files.user-selected.read-write
com.apple.security.files.bookmarks.app-scope
com.apple.security.files.bookmarks.collection-scope
As mentioned above, the second step (resolving the bookmark) completes, but leaves both error and result nil. As I've been implementing sandboxing, most of the mistakes I've made have resulted in an NSError being returned, which helped me to resolve the bug. But now there's no error, and no URL is resolved.
Miscellaneous troubleshooting steps
I tried placing the XML file into my app's sandbox, which didn't make a difference, so access to the XML file is not the problem
The app uses ARC, but so do the unit tests, which succeed. I tried using an alloc/init instead of the autoreleased class method, too (just in case)
I pasted the URL resolution code immediately after creating the bookmark, and it runs fine, producing a security-scoped URL
I did a po on the originally created bookmark (before serialization), and then on the bookmark after deserialization, and they match 100%. Serialization is not the problem
I replaced the resolution call with CFURLCreateByResolvingBookmarkData(..), with no change. If it is a bug, it's present in the Core Foundation API as well as the Cocoa layer
Specifying a value for bookmarkDataIsStale: has no effect
If I specify 0 for options:, then I do get back a valid NSURL, but it has no security scope, and therefore subsequent calls to read the file do still fail
In other words, the deserialized bookmark does appear to be valid. If the bookmark data were corrupted, I doubt NSURL would be able to do anything with it
NSURL.h didn't contain any useful comments to point out something I'm doing wrong
Is anyone else using security-scoped document bookmarks in a sandboxed application with success? If so, what are you doing differently than I am?
OS Version Request
Can someone with access to the Mountain Lion beta verify whether or not my sample project shows the same (lack of an) error? If it's a bug that has been fixed after Lion, I won't worry about it. I'm not in the developer program yet, and so don't have access. I'm not sure if answering that question would violate the NDA, but I hope not.
In your Gist code, change the following line in AppDelegate.m (line 61):
[xmlTextFileData writeToURL:savePanel.URL atomically:YES];
to
[xmlTextFileData writeToURL:savePanel.URL atomically:NO];
Your code will then work.
The reason for this is likely the same reason for which it is necessary to have an existing (but empty) file that will contain the document-scoped bookmarks before calling [anURL bookmarkDataWithOptions]: While creating the NSData instance, the ScopedBookmarkAgent adds something (like a tag, probably an extended file attribute) to that file.
If you write data (i.e. the bookmark URLs) to that file atomically, in fact they're written not directly to the file but first to a temporary file that is renamed if the write operation was successful. It seems that the tag that has been added to the (empty, but existing) file that will contain the bookmarks is getting lost during this process of writing to a temporary file and then renaming it (and thereby likely deleting the original, empty file).
By the way: It shouldn't be necessary to create app-scoped bookmarks before passing the respective URLs to the xml file containing the document-scoped bookmarks.
Addition: com.apple.security.files.bookmarks.collection-scope has been renamed to com.apple.security.files.bookmarks.document-scope in 10.7.4.