Xcode app run on simulator but not on device - ios

i've saw a lot of topic but no one answers to my questions.
This Program run on simulator but when i executed it , it crash .
This is my simple code. Thanks you!
NSURL *url=[NSURL fileURLWithPath:#"/Users/marco/Desktop/Letters/1.txt"];
NSString *fileContent = [NSString stringWithContentsOfURL:url];
NSLog(#"fileContent = %#", fileContent);
NSArray * a = [NSArray arrayWithObjects:fileContent, nil];
Output.text=[a objectAtIndex:0];
NSLog (#"The 4th integer is: %#", a);

Move your 1.txt file to your device, for example your documents folder.
Then change the first line of your app like so:
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [NSString stringWithFormat:#"%#/1.txt", documentsPath];
NSURL *url = [NSURL fileURLWithPath:filePath];

Since you say this works on the simulator, I'll have to assume you added this file to your project properly. If not, add the file to your project and target. You can get the URL to any resource you included at build time through NSBundle:
NSBundle *bundle = [NSBundle bundleForClass:[self class]]; // often you will see [NSBunble mainBundle, but both work
NSURL *url = [bundle URLForResource:#"1" withExtension:#"txt"];

Related

writing string to txt file in objective c

Pulling my hair out trying to work this out. i want to read and write a list of numbers to a txt file within my project. however [string writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error] doesnt appear to write anything to the file. I can see there is the path string returns a file path so it seems to have found it, but just doesnt appear to write anything to the file.
+(void)WriteProductIdToWishList:(NSNumber*)productId {
for (NSString* s in [self GetProductsFromWishList]) {
if([s isEqualToString:[productId stringValue]]) {
//exists already
return;
}
}
NSString *string = [NSString stringWithFormat:#"%#:",productId]; // your string
NSString *path = [[NSBundle mainBundle] pathForResource:#"WishList" ofType:#"txt"];
NSError *error = nil;
[string writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", error.localizedFailureReason);
// path to your .txt file
// Open output file in append mode:
}
EDIT: path shows as /var/mobile/Applications/CFC1ECEC-2A3D-457D-8BDF-639B79B13429/newAR.app/WishList.txt so does exist. But reading it back with:
NSString *path = [[NSBundle mainBundle] pathForResource:#"WishList" ofType:#"txt"];
returns nothing but an empty string.
You're trying to write to a location that is inside your application bundle, which cannot be modified as the bundle is read-only. You need to find a location (in your application's sandbox) that is writeable, and then you'll get the behavior you expect when you call string:WriteToFile:.
Often an application will read a resource from the bundle the first time it's run, copy said file to a suitable location (try the documents folder or temporary folder), and then proceed to modify the file.
So, for example, something along these lines:
// Path for original file in bundle..
NSString *originalPath = [[NSBundle mainBundle] pathForResource:#"WishList" ofType:#"txt"];
NSURL *originalURL = [NSURL URLWithString:originalPath];
// Destination for file that is writeable
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSURL *documentsURL = [NSURL URLWithString:documentsDirectory];
NSString *fileNameComponent = [[originalPath pathComponents] lastObject];
NSURL *destinationURL = [documentsURL URLByAppendingPathComponent:fileNameComponent];
// Copy file to new location
NSError *anError;
[[NSFileManager defaultManager] copyItemAtURL:originalURL
toURL:destinationURL
error:&anError];
// Now you can write to the file....
NSString *string = [NSString stringWithFormat:#"%#:", yourString];
NSError *writeError = nil;
[string writeToFile:destinationURL atomically:YES encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", writeError.localizedFailureReason);
Moving forward (assuming you want to continue to modify the file over time), you'll need to evaluate if the file already exists in the user's document folder, making sure to only copy the file from the bundle when required (otherwise you'll overwrite your modified file with the original bundle copy every time).
To escape from all the hassle with writing to a file in a specific directory, use the NSUserDefaults class to store/retrieve a key-value pair. That way you'd still have hair when you're 64.

How to download dataset for Vuforia app?

I'm developing sample apps from Vuforia SDK 1.5.9 in Xcode 4.2 with iOS 5.1. In that version I could not make my trackable datasets on my own - I have to use online solution from Qualcomm. Does anyone know or have anyone tried to download datasets from remote location? So you generate them as usual but download them into app from server, so I can for example choose which one to download and use on fly?
Yesterday I've given it a quick try with this:
-(void)setupMarkers{
NSString *filePathX;
//connect to the remot location
NSURL *urlD = [NSURL URLWithString:[NSString stringWithFormat:#"%#/frames.dat",kURLServer]];
NSData *urlData = [NSData dataWithContentsOfURL:urlD];
if ( urlData )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"frames.dat"];
[urlData writeToFile:filePath atomically:YES];
}
NSURL *urlX = [NSURL URLWithString:[NSString stringWithFormat:#"%#/frames.xml",kURLServer]];
NSData *urlDataX = [NSData dataWithContentsOfURL:urlX];
if ( urlDataX )
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"frames.xml"];
[urlDataX writeToFile:filePath atomically:YES];
filePathX = filePath;
}
//put them into markersArray
[self.markersArray addObject:filePathX];
}
I know it is ugly, but as I said it was a quick try, but it didn't work at all. I know there is new Vuforia SDK 2.0 with clouds and stuff, but afaik I would have to use iOS6 & Xcode 4.5 - which is not a solution for me right now.
Actually my "quick try" wasn't that bad after all :)
Here's what i did:
wrote a method -(void)setupMarkers in which I dwonload .dat and .xml files (like in question)
in QCARUtils.mm I changed in - (QCAR::DataSet *)loadDataSet:(NSString *)dataSetPath one line:
// Load the data set from the App Bundle
// If the DataSet were in the Documents folder we'd use STORAGE_ABSOLUTE and the full path
if (!theDataSet->load([dataSetPath cStringUsingEncoding:NSASCIIStringEncoding], QCAR::DataSet::STORAGE_ABSOLUTE))//STORAGE_APPRESOURCE)){
...
}
works like a charm :)
p.s. I'll wait a while so if anyone will come up with better answer ;)

.plist path on iOS device

-(void)login{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:#"login" ofType:#"plist"];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
[plistDict setObject:#"si" forKey:#"stato"];
[plistDict writeToFile:path atomically: YES];
}
In iOS Simulator the plist has been correctly written, but when I try to write the .plist on my iPhone, it doesn't work. I guess it is because of the wrong .plist path.
Do the iOS devices use different path?
First you have to check if the file exits in your documents directory. If it doesn't exits there then you can copy it to the document directory. You can do it this way
-(void)login{
BOOL doesExist;
NSError *error;
NSString *filePath= [[NSBundle mainBundle] pathForResource:#"login" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * path =[[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:#"login.plist"]];
doesExist= [fileManager fileExistsAtPath:path];
if (doesExist) {
NSMutableDictionary* plistDict=[[NSMutableDictionary alloc] initWithContentsOfFile:path];
}
else
{
doesExist= [fileManager copyItemAtPath:filePath toPath:path error:&error];
NSMutableDictionary* plistDict=[[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
}
[plistDict setObject:#"si" forKey:#"stato"];
[plistDict writeToFile:path atomically: YES];
}
You can't write to the [NSBundle mainBundle] location. In order to write files like a plist, you should save in the documents folder, this way:
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *filePathToSave = [arrayPaths objectAtIndex:0];
If the plist is part of your app, I would recommend you, in the first launch, to already copy it to the documents folder using the same filePathToSave, so you will always look at it there, both to read or to save.
This is a big mistake, as the main bundle only is readable and only composed at compile time in the App Bundle. The App Bundle lives in a separate place, whereas the data you should write to disk should be placed into the Documents, Temporary or Library folder of your sandbox.
To gain more understanding please read the official File System Programming Guide.
Everything you need to know is written there.
You can also write to subfolders and you should choose between the 3 above mentioned main directories in terms of backing up, when syncing with iTunes or iCloud. For instance contents in the tmp Folder won't be backed up.
You can not write to the mainBundle on an iOS device. You will have to save the file to a directory and modify it there.
Just to bring the answers into the modern world - you should really be using the URL based methods for getting directories:
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSURL *URLForDocumentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]

UIWebview - Loading PNG image - got error

I am trying to load the image(png) in UIWebview. But I got the following error
""ImageIO: PNGinvalid literal/lengths set"
I will get the "png" from the web service. I will store it in the following path. "Users/XXX/Library/Application Support/iPhone Simulator/4.3.2/Applications/E4DE3097-EA84-492F-A2A7-5882202F3B00/Documents/attachement.png "
When I reading the file from the path, I got the error. I am using the following code
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle bundlePath];
NSURL *baseURL = [NSURL fileURLWithPath:path];
NSString *commentHtml = [NSString stringWithFormat:#"<img src=\"%#\"/>", documentEntity.path];
NSString *html3 = [NSString stringWithFormat:#"<html><head/><body><div><b>COMMENTS:</b></div>%#</body></html>", commentHtml];
[self.documentView loadHTMLString:html3 baseURL:baseURL];
Please help me.
THanks
Girija
If you have saved the Image in Documents Folder, why are you fetching from MainBundle.
Fetching Image from the Documents Directory would be :
NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *aFilePath = [NSString stringWithFormat:#"%#/attachement.png", aDocumentsDirectory];
UIImage *anImage = [UIImage imageWithContentsOfFile:aFilePath];

File I/O on iPad

Experts.. a newb question
I have developed a GIS like app which runs perfectly within Xcode and iPad simulator environment. Now I want to test on a real iPAD. I have gone through the provisioning certificates process and able to run the app on my device. The problem comes up when the program tries to read a file which is on my development computer (file path is something like /Users/user/Document/data.txt).
Can I copy that "data.txt" file to ipad and if I can, what will be it's path for I/O.
Thanks for your help.
KAS
You will add it to your application. and it will be in the bundle.
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"data" ofType:#"txt"]];
After you load it up, Parse it with a string.
You can use NSScanner to parse your string
NSString *fileName = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"txt"];
NSError *error = nil;
NSString *myData = [NSString stringWithContentsOfFile:fileName encoding:NSASCIIStringEncoding error:&error];
NSScanner *myScanner = [NSScanner scannerWithString:myData];
int myNewInt = 0;
if ([myScanner scanInt:&myNewInt])
{
//Do Something with my New Int
}
You can include the file in your project then access it. To get the full file path:
NSString *appFolderPath = [[NSBundle mainBundle] resourcePath];
NSString *filePath = [appFolderPath stringByAppendingPathComponent:#"data.txt"];

Resources