I'm implementing a free space on disk bar where while files are being copied, the free space bar updates. I need some way of being notified of file system changes. What's the best way to go about doing this?
The File System Events Programming Guide has all the info you need. You want to register with the File System Events API (OS X 10.5 and later).
To monitor operations on individual files you can use kqueue file change notifications. Uli Kusterer has a nice Obj-C wrapper called UKKQueue.
You can get it here: http://zathras.de/angelweb/sourcecode.htm
If you want to watch an entire folder, FSEvents (and the SCEvents wrapper) will probably be of more use.
Related
I want my Mac Os X sandboxed application to write a log file of every action it takes, I think the correct path would be /Users/MyName/Library/Containers/com.me_developer.myAppID/Data/Library/Logs/. I know how to write a file a append text to it, but what I am looking for is to have old log files archived in a manner similar to system log files are written in /var/log , once they reach a certain size, they are renamed, and compressed (bz2). I wonder if Mac Os X or its lower levels UNIX offers a built in solution for that, and so I wouldn't have to write manually all the code. Thanks.
Take a look at asl, which is the API for interacting with the system log facility in Mac OS X (and iOS). It's a bit low level, in that it's a C API, but it should do everything you want and does so in an Apple-sanctioned, sandboxing-compatible way.
There are a number of third-party, open source Objective-C wrappers for ASL. Here are a few examples (I haven't used any of these, myself):
https://github.com/AlanQuatermain/aqtoolkit/tree/master/ASLogger
https://github.com/billgarrison/SOLogger
https://github.com/nloko/NLOSyslog
Here's a couple articles/tutorials about using ASL:
http://boredzo.org/blog/archives/2008-01-20/why-asl
http://www.cocoanetics.com/2011/03/accessing-the-ios-system-log/
Finally, be sure to take a look at Cocoa Lumberjack, which is a very popular Cocoa logging library.
I'm developing on Cocoa using Xcode. I was wondering if there is a way to lock the embedded resources of my app, like logos, images, sounds, ... so nobody can change them?
Probably the easiest way would be to check timestamps on the resources, but this is also easy to circumvent. A better way would be to compute the hash of your application's resources directory on launch, and compare to a known value.
If any of the resources have been modified then the hash will differ and you can show a message and quit. You could use a custom build script step in Xcode to calculate the hash and have it available at compile time so that the process is all automated.
I understand it may be unpacking some sort of compressed package into the file system (and due to the mobile nature I suppose it may be quite aggressive compression to reduce download time). But does it run any sort of preflight scripts? I suppose it does stuff like register the info.plist, add a pane in Settings.app if you've specified one, and the app's global URL and file type reception registration.
The reason why I'm interested is twofold: curiosity (would there be a way of seeing precisely what's going on? Has anyone investigated this?) and making an installation script. I'm constructing a dictionary app using Core Data (I've thought about this a lot, trust me, I want to use Core Data) and I'd like to have a way of nicely generating the Core Data store from the original XML without degrading the user experience by having some kind of "initializing app". Furthermore I'd like to deploy the dictionary compressed and then uncompress it on the device, to keep it under the 20 mb over the air download limit.
I suppose I could generate the Core Data store on my simulator or dev phone and then add it to the bundle, though that way still seems less than neat. Hence why it would be nice for iOS to handle it for me
Anyway, thoughts?
Whatever the OS does during install, you can be certain that Apple does not offer developers any hook into the operation. There is no way to run any code of your own (install script etc.) until the user first launches your app manually. So do whatever initialization needs to be done on first launch.
The .ipa packages you submit to Apple are already compressed (they are just ZIP files with another file extension) so it should not be necessary to compress a text file yourself to stay under the 20 MB limit. Compressing it twice probably won't help much in terms of file size.
I'd like to store some additional information along with a document, but I can't use bundles or packages, and I cannot store it inside the document itself.
The application is a text editor, and I'd like it to store code folding and bookmark locations with the document, but obviously this cannot be embedded into the code directly, and I don't want to alter the code with ugly comments.
Can I use NSDocument to store information in the resource fork of a document? If so, how can I do this? Should I directly write to <filename>/..namedfork/rsrc or is there an API available?
First, don't use the resource fork. It's virtually deprecated. Instead, use extended attributes. They can be set programmatically at the BSD level via setxattr and getxattr. Extended attributes are used in many places... for example, in the latest OS X, the resource fork itself is implemented as a special type of extended attributes.
For example, the Cocoa text system automatically adds an extended attribute to a file to specify the encoding.
I thought NSFileManager and NSFileWrapper supported extended attributes since Snow Leopard, but I can't find any documentation :p You can always use the BSD level functions, though.
Does the state need to move with the file if it's copied to another computer? If not, you could do a lot worse than emulating the way Bare Bones handles document state with BBEdit. They store state for all documents in ~/Library/Preferences/com.barebones.bbedit.PreferenceData/Document State.plist.
The resource fork documentation is here. But it contains plenty of suggestions to not use the resource fork.
I have a class on my web site for reading and writing resource forks, which I have never got around to moving to my GitHub repository because, as Yuji points out, they are not really used any more.
I was going to say alias files and web Internet location file are the only places they are used, but I used and tested it on Mac OS X v10.7 (Lion), and they are not even used there any more; they may still be used for custom icons. I didn't test for that exclusively. I will have to see how that affect my NDAlias class on 10.7.
ndresourcefork
I'd like to be able to track file read/writes of specific program invocations. No information about the actual transactions is required, just the file names involved.
Is there a cross platform solution to this?
What are various platform specific methods?
On Linux I know there's strace/ptrace (if there are faster methods that'd be good too). I think on mac os there's ktrace.
What about Windows?
Also, it would be amazing if it would be possible to block (stall out) file accesses until some later time.
Thanks!
The short answer is no. There are plenty of platform specific solutions which all probably have similar interfaces, but they aren't inherently cross platform since file systems tend to be platform specific.
How do I do it well on each platform?
Again, it will depend on the platform :) For Windows, if you want to track reads/writes in flight, you might have to go with IFS. If you just want to get notified of changes, you can use ReadDirectoryChangesW or the NTFS change journal.
I'd recommend using the NTFS change journal only because it tends to be more reliable.
On Windows you can use the command line tool Handle or the GUI version Process Explorer to see which files a given process has open.
If you're looking for a get this information in your own program you can use the IFS kit from Microsoft to write a file system filter. The file system filter will show all file system operation for all process. File system filters are used in AV software to scan files before they are open or to scan newly created files.
As long as your program launches the processes you want to monitor, you can write a debugger and then you'll be notified every time a process starts or exits. When a process starts, you can inject a DLL to hook the CreateFile system calls for each individual process. The hook can then use a pipe or a socket to report file activity to the debugger.