Open/edit a .txt file located in application bundle with NSTextView object - cocoa

I would like to add an NSTextView object to my app and add an action that opens a .txt file located in the app bundle in the textView. Also - I would like to have the option to edit and save the edited doc without renaming it. So standard save, not save as.
What's the best way to handle this?

Use NSString to load the file and put it in your text view:
NSTextView *textView; //your NSTextView object
NSError *err = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:#"EditableFile" ofType:#"txt"];
NSString *contents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&err];
if(!contents) {
//handle error
}
[textView setString:contents];
Saving is just the opposite. Get the string and write it to the file:
NSTextView *textView; //your NSTextView object
NSError *err = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:#"EditableFile" ofType:#"txt"];
NSString *contents = [textView string];
if(![contents writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&err]) {
//handle error
}

Related

attachment not sent with email from ipad

I have an iPad that has a routine to create a pdf and send as an attachment to an email. It all seems to work with the email composer opening showing the pdf document attached. However when tested on an iPad, when the email is received there is no attachment. Any ideas?
[mailComposer addAttachmentData:data mimeType:#"application/pdf" fileName:#"pdffile.pdf"];
[self presentViewController:mailComposer animated:YES completion:nil];
Many thanks
Detail:
The pdf file is created and called pdffile.pdf. The following is the full email routine:
MFMailComposeViewController *mailComposer;
mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setModalPresentationStyle:UIModalPresentationFormSheet];
[mailComposer setSubject:[NSString stringWithFormat: #"i-observe Lesson Observation for: %s", "date"]];
[mailComposer setMessageBody:[NSString stringWithFormat: #"i-observe Lesson Observation for: %s", "name"] isHTML:NO];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file = [documentsDirectory stringByAppendingFormat:#"pdffile.pdf"];
NSMutableData *data=[NSMutableData dataWithContentsOfFile:file];
[mailComposer addAttachmentData:data mimeType:#"application/pdf" fileName:#"pdffile.pdf"];
[self presentViewController:mailComposer animated:YES completion:nil];
Try This Method:
if([MFMailComposeViewController canSendMail]){
MFMailComposeViewController *mail=[[MFMailComposeViewController alloc]init];
mail.mailComposeDelegate=self;
[mail setSubject:#"Email with attached pdf"];
NSString *newFilePath = #"get path where the pdf reside";
NSData * pdfData = [NSData dataWithContentsOfFile:newFilePath];
[mail addAttachmentData:pdfData mimeType:#"application/pdf" fileName:#"yourpdfname.pdf"];
NSString * body = #"";
[mail setMessageBody:body isHTML:NO];
[self presentModalViewController:mail animated:YES];
[mail release];
}
else
{
NSLog(#"Message cannot be sent");
}
The next solutions is based assuming that the pdf file is in your main bundle:
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *myFile = [mainBundle pathForResource: #"RealNameofFile" ofType: #"pdf"];
NSData *pdfD = [NSData dataWithContentsOfFile:myFile];
[mailViewController addAttachmentData:pdfData mimeType:#"application/pdf" fileName:#"Nametodisplayattached.pdf"];
make sure that the file has the same name as the table cell

XCode - UIWebView Not Loading

I have two local .html files in the Resources folder. I'm trying to load them the following way, but only the final page loads. What am I doing wrong?
File = please_wait.html
This one does not work.
NSError *error;
NSString* path = [[NSBundle mainBundle] pathForResource:#"please_wait" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
[webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:path]];
//Big "do-while" loop here. It works fine so I omitted it.
File = update_graph.html
This one does not work
path = [[NSBundle mainBundle] pathForResource:#"update_graph" ofType:#"html"];
htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
[webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:path]];
//Lots of code removed. All works correctly and doesn't touch webview
This last one works perfectly. Google displays.
string = #"http://google.com";
NSURL *url = [NSURL URLWithString: string];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
It appears from your comment that your UIWebView loads just fine, but it does not get a chance to refresh itself on the screen until you exit your method. It is not enough to set a break point inside the method and wait for the view to load: you must exit the method before iOS realizes that it needs to call UIWebView's drawRect method.
To fix this, split your method in three parts, A B and C, and set UIWebView's delegate in A to invoke B on webViewDidFinishLoad:, and the delegate in B to call C.
Here is how to implement this: start with a delegate that can call a selector when the loading has completed:
#interface GoToNext : NSObject <UIWebViewDelegate> {
id __weak target;
SEL next;
}
-(id)initWithTarget:(id)target andNext:(SEL)next;
-(void)webViewDidFinishLoad:(UIWebView *)webView;
#end
#implementation GoNext
-(id)initWithTarget:(id)_target andNext:(SEL)_next {
self = [super init];
if (self) {
target = _target;
next = _next;
}
return self;
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[target performSelector:next];
#pragma clang diagnostic pop
}
#end
Now split your method into three parts - loading the first page, loading the second page, and loading the third page:
-(void)loadPleaseWait {
NSError *error;
NSString* path = [[NSBundle mainBundle] pathForResource:#"please_wait" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
webView.delegate = [[GoToNext alloc] initWithTarget:self andNext:#selector(loadUpdateGraph)];
[webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:path]];
// big do-while loop
}
-(void)loadUpdateGraph {
NSError *error;
NSString* path = [[NSBundle mainBundle] pathForResource:#"update_graph" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
webView.delegate = [[GoToNext alloc] initWithTarget:self andNext:#selector(loadGoogle)];
[webView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:path]];
// Lots of code removed
}
-(void)loadGoogle {
string = #"http://google.com";
NSURL *url = [NSURL URLWithString: string];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
}

Problems adding data to a plist file

I've been trying to write data back to a pre-defined plist file (data.plist) in my bundle. Using the code below I call the routine 'dictionaryFromPlist' to open the file and then call 'writeDictionaryToPlist' to write to the plist file. However, no data gets added to the plist file.
NSDictionary *dict = [self dictionaryFromPlist];
NSString *key = #"Reports";
NSString *value = #"TestingTesting";
[dict setValue:value forKey:key];
[self writeDictionaryToPlist:dict];
- (NSMutableDictionary*)dictionaryFromPlist {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"];
NSMutableDictionary* propertyListValues = [[NSMutableDictionary alloc]
initWithContentsOfFile:filePath];
return [propertyListValues autorelease];
}
- (BOOL)writeDictionaryToPlist:(NSDictionary*)plistDict{
NSString *filePath = #"data.plist";
BOOL result = [plistDict writeToFile:filePath atomically:YES];
return result;
}
The code runs through successfully and no error is thrown but no data is added to my plist file.
You can not write to your bundle, it is read only. If your case though, you are writing to a relative path, not to the bundle.
I'm not sure what the default working directory is for iOS apps. It is best to use absolute paths. You should be writing to the documents/cache directory. Something like this will get the path for you:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
Then just grab the lastObject and prepend that to your file name.
As mentioned by #logancautrell you can not write in mainbundle, you can save your plist in the app documents folder, you could do so:
NSString *path = #"example.plist";
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count]> 0)? [paths objectAtIndex: 0]: nil;
NSString *documentPath = [basePath stringByAppendingPathComponent:path] // Documents
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL checkfile = [fileManager fileExistsAtPath: documentPath];
NSLog(#"%#", (checkFile ? #"Exist": #"Not exist"));//check if exist
if(!checkfile) {//if not exist
BOOL copyFileToDoc = [yourDictionary writeToFile:documentPath atomically: YES];
NSLog(#"%#",(copyFileToDoc ? #"Copied": #"Not copied"));
}

xcode debugging terminates when i run app

When I run my app in Xcode using the simulator it runs just file until I add in the first three lines involving the text file. It gives me a message saying terminate called after throwing an instance of 'NSException'. I don't know what that means or why it only happens when I try to read in the text file and display it in the textView.
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"textfiles/brain_01" ofType:#"txt"];//establish file path for text file
NSString *textFile = [[NSString alloc] stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error: nil];
textView.text = textFile;
[super viewDidLoad];
fullButton.hidden = YES;
viewLabel.hidden = YES;
}
NSException means your code has a bug in it. An exception is an error. In your case, it's probably because
NSString *textFile = [[NSString alloc] stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error: nil];
should be
NSString *textFile = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error: nil];
stringWithContentsOfFile is a class method used to make NSString -- only use alloc with init... methods.

set lastPathComponent string after save

Doc based, QTKit app. When saving, the new filename updates in the active window titleBar. I would also like to display the newly saved filename string in a textField, somewhere else on the opened doc. The code successfully saves the new doc. However the lastPathComponent string doesn't update. Please advise?
thanks,
Paul
- (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
NSURL *outputFileURL = [(NSURL *)contextInfo autorelease];
if (returnCode == NSOKButton) {
NSString *filename = [sheet filename];
[[NSFileManager defaultManager] moveItemAtPath:[outputFileURL path] toPath:filename error:nil];
NSString *path = [filename lastPathComponent];
[textField setStringValue:[path lastPathComponent]];
[[NSWorkspace sharedWorkspace] openFile:filename];
}
else {
[[NSFileManager defaultManager] removeItemAtPath:[outputFileURL path] error:nil];
}
}
Since "filename" is apparently valid (because things are working and your window title updates), have you checked to make sure "textField" is actually connected in your XIB?

Resources