2

I have written virtual system (VFS) that I am using for my apps on Windows. Now, I moved my application to iOS and I have issue with dirrent.

Windows port has added info about current folder, where file is.

DIR * dir = opendir(dirName);
char * dirFullPath = dir->patt; //this is missing at iOS

How can I get that info ? DirName variable is useless, since its only relative path.

And second, on windows I specify folder to be mapped as root of my VFS. How can I do the same for iOS ? Lets say, to map VFS to directory DATA.

Martin Perry
  • 9,232
  • 8
  • 46
  • 114
  • Don't use a string for paths. That is a bad idea. You should be using NSURL. Feel free to write your own C++ wrapper, but it should be using NSURL under the hood when compiled for iOS. Have your wapper use the recommended API on Windows or any other platform. – Abhi Beckert Aug 25 '13 at 08:27
  • 1
    I dont see nothing wrong with char *. NSURL is NOT ANSI C++ compatible and this solution will be mess. Now I have same code and I can port it everywhere with minor changes. – Martin Perry Aug 25 '13 at 08:41

2 Answers2

1

NSSearchPathForDirectoriesInDomains() is a low level API that should be avoided unless you need it for some unusual reason. Instead you should be using NSURL. This is Apple's official recommendation:

The NSSearchPathForDirectoriesInDomains function behaves like the URLsForDirectory:inDomains: method but returns the directory’s location as a string-based path. You should use the URLsForDirectory:inDomains: method instead.

It's used like this:

NSURL *documentsURL = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject;

The NSURL object does exactly what you want: it's an object that contains a base URL and then a relative URL under that.

If you are writing a cross platform app you need to write a wrapper around everything that is not cross platform, and filesystem operations are one of the things you need to abstract. Write a C++ wrapper around NSURL and NSFileManager, and have your wrapper use something else on other platforms.

NSURL is generally faster and less buggy reliable and uses less RAM than using strings. Often it uses low level filesystem/sector references.

Abhi Beckert
  • 32,787
  • 12
  • 83
  • 110
  • 1
    need to write a wrapper around everything that is not cross platform - that is not entirely true. dirent.h is C UNIX library for filesystem operations and works fine. Only problem for me was, to find start directory. I am able to print-out full filesystem with my code without problem (I have also archive support). NSURL may be safer, but strings are multiplatform. – Martin Perry Aug 25 '13 at 08:46
  • @MartinPerry yes but UNIX filesystem libraries are essentially deprecated on OS X and iOS. The history is Mac OS 9/classic had FSRef and NeXT used the standard UNIX libraries, and both had different strengths and weaknesses. You can use either one of those today (and many people still do), but NSURL has been created to merge the strengths of both API's and it is what you should be using. It's faster, has more features, and less bugs/gotcha's. Some things, such as full disk encryption and filesystem entitlements are poorly supported by dirent.h. – Abhi Beckert Aug 25 '13 at 09:17
  • 1
    Yes.. but UNIX libraries should work OK as well. Deprecated != not working :) And as I said, rewrite whole VFS to use NSURL would be too complicated and in my point of view also pointless, as far as UNIX libs are working. – Martin Perry Aug 25 '13 at 09:21
  • @MartinPerry that depends on your definition of "working". For example if you want ideal performance and if you want compatibility with things like iCloud and if you want your app not to crash when something weird happens like iTunes making a backup while your app is running... then you should be using NSURL (or CFURLRef). NSURL is the recommended API *because nothing else is suitable*. There are good reasons to use it. – Abhi Beckert Aug 25 '13 at 09:47
  • 1
    I only use it for my VFS initialization, to scan directory for archives (and subdirectories). Than I add virtual pointers to files in archive. When I really need file, zlib unzip archive and return memory stream with unziped file. – Martin Perry Aug 25 '13 at 09:54
0

See `NSFileManager as it provides the standard iOS interface to the filesystem.

https://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/Reference/Reference.html

As well, you should understand this thoroughly.

https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemProgrammingGuide.pdf

(See the iOS section)

bbum
  • 162,346
  • 23
  • 271
  • 359
  • I am not using Objective-C, but C++... NSFileManager is Objective-C only, so useless.. – Martin Perry Aug 24 '13 at 17:46
  • 5
    Sounds like you are purposefully choosing the most painful route of development. Good luck with that (I mean that-- not sarcasm-- this is a decidedly alien route to take, but you'll certainly learn a lot along the way). You'll probably be best off w/a C++ wrapper around your FS operations which is then backed by NSFileManager on iOS. – bbum Aug 24 '13 at 23:12
  • `Sounds like you are purposefully choosing the most painful route of development` - I am doing multiplarform application for iOS, Android, Windows, Linux... So most of the code must be in ANSI C++. The less I need to write in native code (Objective-C, Java, C#..), the better – Martin Perry Aug 25 '13 at 06:32