Loading XML config from URL on iOS - [Metaio SDK] - ios

in must examples of Metaio SDK docs the xml's are loaded from Assets folder (more specifically, from NSBundle in iOS).
But in iOS, you can't write into a file in your app's bundle -- the entire bundle is read-only
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/index.html
In my project I need download all stuff to working with Metaio SDK, things like Videos, Sounds, 3D models and trackable images and your xml configs.
For example, from the Metaio docs, to work with a XML then are in Assets, are easy like:
NSString* MarkerTrackingFile = [[NSBundle mainBundle] pathForResource:#"tracking" ofType:#"xml" inDirectory:#"Assets/tracking"];
But how I said, I need to get this XML from internet, so, to do this I make an method to download.
(This is just a dirty code for study, not optimized without threads and anything special, for now)
/*********************************************/
-(void)downloadXML{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"markerless_tracking.xml"];
NSString *contents = [NSString stringWithContentsOfFile:filePath];
NSLog(#"%#", contents);
}
After this download, I try to use this XML in my project, I confirmed this consistence, but not work when I call him with this method, but i receive the message from error: No success loading the tracking configuration
- (void) loadTrackingConfigurationFiles
{
// Markerless tracking configuration file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* markerlessTrackingFile = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"markerless_tracking.xml"];
// We apply the correct one to the SDK
if(markerlessTrackingFile)
{
bool success = m_metaioSDK->setTrackingConfiguration([markerlessTrackingFile UTF8String]);
if( !success)
NSLog(#"No success loading the tracking configuration");
}
}
My main question is: Is possible loading a xml from outside NSBundle folder in METAIO SDK? In my project i don't have anything in local folders, everything is downloaded, tracking images, videos, sounds, xml etc, is viable the use Metaio SDK for this purpose?
I appreciate any help, examples or suggestions.

Related

iOS10 filesystem - are files no longer in app container?

For debugging purposes I've often written data to files on iOS using code such as this...
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [docsPath stringByAppendingPathComponent:testName];
FILE* resultsFile = fopen([filePath UTF8String],"w");
...and then gotten the data by downloading the container via Xcode (by selecting the app on the "Window->Devices" screen, and choosing "Download container..." from the "little gear" pop-up menu just below the list of apps.)
I recall this working on iOS 9 and previous, but trying this on iOS 10 on an iPhone 6, I'm finding it doesn't work anymore. The call to fopen is returning success for /var/mobile/Containers/Data/Application/[uuid]/Documents/testname but the file isn't in the container when I download it.
Shouldn't the file be in the container? Is it elsewhere? Or is it simply not possible to dump data to a file and pull it off the phone anymore?
I have tried to reproduce your problem (under iOS 10.3.3, Xcode 10.1) and it all worked on my end in the context of an App project. The issue you have may be related to what you do with the file object resultFile, if you could share some code containing the next lines of your code (or check that you are calling fclose() for example), it may be easier to solve it.
Also please note that it is seems NOT supported to write to the Docs directory from the code controlling an App Extension as detailed here: reading and writing to an iOS application document folder from extension
Code that worked in the context of an App project / target:
using Data in Swift like this:
guard let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else { return }
let someData = "Hello world using swift".data(using: .utf8)
do{
try someData?.write(to: documentsPath.appendingPathComponent("hello-world.txt"))
}catch{
//handle the write error
}
using NSData with Objective C:
NSString * hello = #"Hello world using NSData";
NSData * helloData = [hello dataUsingEncoding: NSUTF8StringEncoding];
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [docsPath stringByAppendingPathComponent:#"fileNameObjcNSData.txt"];
[helloData writeToFile:filePath atomically:true];
using fopen:
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *filePath = [docsPath stringByAppendingPathComponent:#"fileNameObjcFopen.txt"]; //
FILE * fileHandle = fopen([filePath UTF8String], "w");
if (fileHandle != NULL){
fputs("Hello using fopen()", fileHandle);
fclose(fileHandle);
}
Hope it helps

A Picker controller similar to UIImagePickerController to pick files ios 7

Just as we have UIImagePickerController to pick images into our iOS app. Is there a way to import the files in a similar manner as well? iOS 8 suggests a UIDocumentPickerViewController, but only for files in iCloud. Is there a way to import files in iOS 7?
Thanks!
Kaushil Ruparelia
iOS 8 allows you UIDocumentPickerViewController for picking files on iCloud. Other file inside your iDevice could not load or find with this controller.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
for (NSString *s in fileList){
NSLog(#"%#", s);
}
You can access files from your App Sandbox, and Some other type like, Images/Videos through UIImagePickerViewController.
In short, There is no way to get other files directly through any controller :(
HTH, Enjoy Coding !!

NSKeyedArchiver not persisting data

So, my app queries an Amazon Dynamo DB database and retrieves a few kilobytes worth of data. What I want the app to do is download everything the first time, and then every time after, just download a timestamp to see if it has the most recent version of the data. So that I only have to download the data every once in a while, I'm trying to use NSKeyedArchiver to archive the array that I'm downloading. I have tried this three different ways, and none of them work on an iPhone, although two of them work on the simulator.
[NSKeyedArchiver archiveRootObject:self.dataArray toFile:#"dataArray.archive"];
This does not work on the simulator nor the actual iphone. The result of this method is NO.
The next thing I used was the full path:
[NSKeyedArchiver archiveRootObject:self.dataArray toFile:#"Users/Corey/Desktop/.../dataArray.archive"];
And this worked on the simulator, but not on the iPhone. My guess was that when compiled, the filesystem looks different (and obviously doesn't have the same path). So next I tried:
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"dataArray" ofType:#".archive"];
[NSKeyedArchiver archiveRootObject:self.dataArray toFile:filePath];
Once again, this works on the simulator but fails on the iphone. I have confirmed that all of the data is in self.dataArray before writing to the archive, and confirmed that the array is nil after writing back to the archive (in the iphone version). Any ideas what's going on? Is there a better way to do the filepath?
This is what I tracked down:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent: #"dataArray.archive"];
[NSKeyedArchiver archiveRootObject:your_object toFile:filePath];
and it worked perfectly on both the simulator and the iPhone!
[NSKeyedArchiver archiveRootObject:self.dataArray toFile:#"dataArray.archive"];
You have to provide a full path.
[NSKeyedArchiver archiveRootObject:self.dataArray toFile:#"Users/Corey/Desktop/.../dataArray.archive"];
That is not a full path. A full path begins with / and does not have /../ anywhere.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"dataArray" ofType:#".archive"];
You do not have permission to write inside the mainBundle, it is read only.
Also, in general you shouldn't use file paths, you should use URLs. Some APIs (including this one) requires a path but URLs are the recommended approach these days.
Here's the proper way to write the file to disk:
NSURL *applicationSupportUrl = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask][0];
applicationSupportUrl = [applicationSupportUrl URLByAppendingPathComponent:#"My App"]; // replace with your app name
if (![applicationSupportUrl checkResourceIsReachableAndReturnError:NULL]) {
[[NSFileManager defaultManager] createDirectoryAtURL:applicationSupportUrl withIntermediateDirectories:YES attributes:#{} error:NULL];
}
NSURL *archiveUrl = [applicationSupportUrl URLByAppendingPathComponent:#"foo.archive"];
[NSKeyedArchiver archiveRootObject:self.dataArray toFile:archiveUrl.path];

How to access and display documents from iPad3 programatically?

I am implementing an application that allows users to add and share different documents. I am done with adding documents by enabling "Application supports iTunes file sharing" in the plist. So user can add his/her documents directly to the application with the help of iTunes. Now my problem is I need access and display all documents under my application in a table view with their title. Based on the user selection I need to display it in a pdf or any other format.
How can I access all the documents under my application?
Also is there any other way to dump documents in to my application except using iTues? Please suggest a better option.
I found a solution for this. By using the following code snippet we can easily access all the files.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
for (NSString *s in fileList)
{
if ([s hasSuffix:#".pdf"])
{
//do stuff
}
else
{
// do stuff
}
}

iPhone App Update. "createSymbolicLinkAtPath" released?

I am using the symbolic link with iPhoneApp.
NSString* js_path = [[NSBundle mainBundle] pathForResource:#"js" ofType:nil];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if (js_path != nil) {
NSFileManager *fm = [NSFileManager defaultManager];
NSString* move_js_path = [NSString stringWithFormat:#"%#/js", [paths objectAtIndex:0]];
NSError *error;
if ([fm createSymbolicLinkAtPath:move_js_path withDestinationPath:js_path error:&error]) {
} else {}
}
I updated the application program. It becomes impossible to read the file afterwards.
However, the file was able to be read by reinstalling it after the application program had been deleted once.
Is there a problem in this code?
If anyones wondering about this, the reason is the application moves directory every time it's updated, the solution might be to use relative paths bundles are located at /var/mobile/Applications/[unique id that changes every update]/app.app whereas the documents directory is located at /var/mobile/Applications/[unique id that changes every update]/Documents so a symlink from Documents to the bundle will always work if it uses something like ../[bundlepath lastPathComponent]/Documents
ofc it's a good idea to build the relativeness from the directories you get at runtime rather than hard coding it, incase these relative paths change in the future.

Resources