Image cannot be saved using UIImageWriteToSavedPhotosAlbum to photo album - objective-c

I have a save button called save to photo album. On top of the button is the small UIImageView where user can click the button below to save the actual size of the photo to photo album. My problem is that when I click the save button, it shows an error : Unable to save image to Photo Album.
I think I have done it right but my experience is too limited.
H file:
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController {
IBOutlet UIButton *btnReturn;
IBOutlet UIButton *savePhoto;
IBOutlet UIImage *saveImage;
}
#property (nonatomic, retain) IBOutlet UIButton *btnReturn;
#property (nonatomic, retain) IBOutlet UIButton *savePhoto;
#property (nonatomic, retain) IBOutlet UIImage *saveImage;
-(IBAction) saveToPhotoAlbum;
#end
Below is my code:
-(IBAction) saveToPhotoAlbum{
NSString *saveMyPhoto=[NSHomeDirectory() stringByAppendingPathComponent:#"sample.png"];
UIImage *saved=[UIImage imageWithContentsOfFile:saveMyPhoto];
NSData *imageData = [NSData dataWithContentsOfFile:(NSString *)UIImagePNGRepresentation(saved)];
[imageData writeToFile:(NSString *)saved atomically:YES ];
UIImageWriteToSavedPhotosAlbum(saved, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
UIAlertView *alert;
if (error)
alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Unable to save image to Photo Album."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
else
alert = [[UIAlertView alloc] initWithTitle:#"Success"
message:#"Image saved to Photo Album."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}

Just create a UIImage object and load the image from file. Then just call the UIIMageWriteToSavedPhotoAlbum function and pass the UIImage object as the first parameter and then the rest could all be NIL. See the Apple SDK documentation.

These lines look really really suspect :
NSString *saveMyPhoto=[NSHomeDirectory() stringByAppendingPathComponent:#"sample.png"];
...
UIImage *saved = [UIImage imageWithContentsOfFile:saveMyPhoto];
...
[imageData writeToFile:(NSString *)saved atomically:YES ];
What are you expecting this to do? You get a path to an image, load it and then save it again but you've cast a UIImage to an NSString and are hoping it will magically turn into a valid path on the disk?
As for the question you're asking, are you sure that your image is a valid image?

Related

iOS: NSString when uploaded to parse.com shows blank

I have taken an NSString from one class to another to be saved on parse.com
I have a quiz view controller where a user enters a question in a UITextView and then they press next to go to the select friends view controller where they select a user and then send the question over parse.
quiz.h
#property (nonatomic,strong) IBOutlet UITextView *textField;
#property (nonatomic, strong) NSString *text;
quiz.m
- (void)viewDidLoad {
[super viewDidLoad];
UITextView *textView = [[UITextView alloc] init];
NSString *text = self.textField.text;
selectFriendsViewController *sfvc = [[selectFriendsViewController alloc] init];
sfvc.string = text;
}
- (IBAction)next:(id)sender {
if ([text length] == 0) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error!"
message:#"Enter some text"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
} else {
}
}
selectfriendsviewcontroller.h
#property (nonatomic, strong) NSString *string;
selectfriendsviewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
quizViewController *qvc = [[quizViewController alloc] init];
qvc.text = string;
UITextView *textfield = [[UITextView alloc] init];
string = textfield.text;
NSLog(#"%#", self.string);
}
if i remove everything except the NSLog in the selectfriends.m file in viewdidload method, the file wont upload to parse. and i get the alertView showing and error saying not file or directory exists.
then i upload to parse.com
- (void) uploadMessage;
{
NSString *text =string;
NSString *fileType= #"text";
NSString * fileName= #"text.txt";
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
PFFile *file = [PFFile fileWithName:fileName data:data];
[file saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please try sending your message again" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
1) the string does not pass as null as null does not show in the console at runtime. (nothing shows in the console even with the NSLog statement)
2) the file uploads to parse.com as a text.txt file but when i download the file to check the text the file is blank.
So in quizVC type a question then press next to go to selectfirendsVC then select friends and upload to parse.com
how can i upload the textfile to show the user inputted text in the UITextView in the quizVC?
You don't want to communicate with just any instance of your SelectFriends vc, like the one created in your viewDidLoad. You must communicate with the instance that is going to be presented.
Remove the code in Quiz vc's viewDidLoad. Create a segue from Quiz vc to SelectFriends vc. In Quiz vc, implement prepareForSegue. In that method, interrogate the textView's text and set the string property on the segue.destinationViewController. That's the one that will be presented.
(A more general treatment of vc-vc communication here).

Same algorithms with NSMutableArray and SetImage with different names work differently

So I have a problem.
I have :
NSMutableArray *photos_imagesArray;
NSMutableArray *myPhotos_imagesArray;
Declared in the .h file inside of #interface EXViewController.
What I do is:
For one view - photos_viewController - I take image data from photos_imagesArray and use setImage on an UIImageView on this view. Everything works.
Now, when I do exactly the same thing but with the myPhotos_viewController and with the myPhotos_imagesArray - setImage does not fire up and myPhotos_imagesArray gets emptied.
Why the heck is this working this way? I have two very identical algorithms working in two as well identical Views and yet I get different results. All that is different is a couple of names. XCode isn't even showing me any errors.
Update 1 (Shared the code):
The place in the EXViewController.h where I declared the mutable arrays.
#interface EXViewController : UIViewController <UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
UIImagePickerController *upload_imagePickerCamera;
UIImagePickerController *upload_imagePickerLibrary;
UIImage *upload_imageUploaded;
IBOutlet UIImageView *upload_imageViewUploadedImage;
// Photos Currently viewed
NSInteger _photoIndex;
NSMutableArray *photos_imagesArray;
NSMutableArray *myPhotos_imagesArray;
}
And the functions:
For the part that works -
// PHOTOS
-(void)goToPhotos {
[photos_imagesArray removeAllObjects];
_photoIndex = 0;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewControllerPhotos = [mainStoryboard instantiateViewControllerWithIdentifier:#"viewControllerPhotos"];
[self presentViewController:viewControllerPhotos animated:true completion:nil];
PFQuery *query_photos = [PFQuery queryWithClassName:#"Photo"];
[query_photos orderByDescending:#"createdAt"];
[query_photos findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// Copy objects array to photos array
photos_imagesArray = [objects mutableCopy];
// Set Current photo
[self photos_setCurrentPhoto];
} else {
NSString *errorString = [error userInfo][#"error"];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Error" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}];
}
-(void)photos_setCurrentPhoto{
if ([photos_imagesArray count] != 0) {
PFFile *userImageFile = photos_imagesArray[_photoIndex][#"imageFile"];
[userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
if (!error) {
UIImage *image = [UIImage imageWithData:imageData];
[self.photos_imageViewCurrent setImage:image];
}
}];
}
}
And for the part that doesn't -
// MY PHOTOS
-(void)myPhotos_goToMyPhotos{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewControllerPhotos = [mainStoryboard instantiateViewControllerWithIdentifier:#"viewControllerMyPhotos"];
[self presentViewController:viewControllerPhotos animated:true completion:^{
PFQuery *query_photos = [PFQuery queryWithClassName:#"Photo"];
[query_photos whereKey:#"userId" equalTo:[PFUser currentUser].objectId];
[query_photos orderByDescending:#"createdAt"];
[query_photos findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
_photoIndex = 0;
// Copy objects array to photos array
myPhotos_imagesArray = [objects mutableCopy];
NSLog(#"%i",[myPhotos_imagesArray count]);
// Set Current photo
[self myPhotos_setCurrentPhoto];
} else {
NSString *errorString = [error userInfo][#"error"];
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Error" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}];
}];
}
-(void)myPhotos_setCurrentPhoto{
if ([myPhotos_imagesArray count] != 0) {
// Set photo in image view
PFFile *userImageFile = myPhotos_imagesArray[_photoIndex][#"imageFile"];
[userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
if (!error) {
UIImage *image = [UIImage imageWithData:imageData];
self.myPhotos_imageViewCurrentPhoto.image = image;
}
}];
}
}
P.S I tried the algorithm inside and outside the completion callback - same results.
Update 2 (added the whole EXViewController.h file):
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface EXViewController : UIViewController <UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
UIImagePickerController *upload_imagePickerCamera;
UIImagePickerController *upload_imagePickerLibrary;
UIImage *upload_imageUploaded;
IBOutlet UIImageView *upload_imageViewUploadedImage;
// Photo Currently viewed
NSInteger _photoIndex;
NSMutableArray *photos_imagesArray;
NSMutableArray *myPhotos_imagesArray;
}
// Login Form
#property (strong, nonatomic) IBOutlet UITextField *login_fieldEmail;
#property (strong, nonatomic) IBOutlet UITextField *login_fieldPassword;
- (IBAction)login_buttonSignInAction:(id)sender;
- (IBAction)login_buttonForgotAction:(id)sender;
// Sign Up Form
#property (strong, nonatomic) IBOutlet UITextField *signup_fieldEmail;
#property (strong, nonatomic) IBOutlet UITextField *signup_fieldPassword;
#property (strong, nonatomic) IBOutlet UITextField *signup_fieldCountry;
#property (strong, nonatomic) IBOutlet UISegmentedControl *signup_fieldSex;
#property (strong, nonatomic) IBOutlet UITextField *signup_fieldYear;
- (IBAction)buttonSignupAction:(id)sender;
// Photos
#property (weak, nonatomic) IBOutlet UIImageView *photos_imageViewCurrent;
- (IBAction)photos_buttonRatePlus:(id)sender;
- (IBAction)photos_buttonRateMinus:(id)sender;
// Menu
- (IBAction)menu_buttonSignOutAction:(id)sender;
- (IBAction)menu_buttonMyPhotos:(id)sender;
// Upload Photo
- (IBAction)upload_buttonTakePhoto:(id)sender;
- (IBAction)upload_buttonPhotoAlbum:(id)sender;
- (IBAction)upload_buttonUpload:(id)sender;
#property (strong, nonatomic) IBOutlet UIProgressView *upload_progressViewUpload;
#property (strong, nonatomic) IBOutlet UILabel *upload_labelImageUploaded;
#property (strong, nonatomic) IBOutlet UIActivityIndicatorView *upload_gravity;
// My Photos
#property (weak, nonatomic) IBOutlet UIImageView *myPhotos_imageViewCurrentPhoto;
#property (weak, nonatomic) IBOutlet UILabel *myPhotos_labelRating;
#property (weak, nonatomic) IBOutlet UILabel *myPhotos_labelVotes;
- (IBAction)myPhotos_buttonNext:(id)sender;
- (IBAction)myPhotos_buttonPrevious:(id)sender;
#end

EXC_BAD_ACCESS in UIWebView delegate

I've got a problem - I'm getting EXC_BAD_ACCESS when trying to set UIWebView.delegate = self;
My code:
vkLogin.h -
#import UIKit/UIKit.h
#interface vkLogin : UIViewController <UIWebViewDelegate>
{
UIWebView *authBrowser;
UIActivityIndicatorView *activityIndicator;
}
#property (nonatomic, retain) UIWebView *authBrowser;
#property (nonatomic, retain) UIActivityIndicatorView *activityIndicator;
#end
vkLogin.m -
#import "vkLogin.h"
#import "bteamViewController.h"
#implementation vkLogin
#synthesize authBrowser;
- (void) viewDidLoad
{
[super viewDidLoad];
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.center = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.size.height / 2);
activityIndicator.autoresizesSubviews = YES;
activityIndicator.hidesWhenStopped = YES;
[self.view addSubview: activityIndicator];
[activityIndicator startAnimating];
authBrowser = [[UIWebView alloc] initWithFrame:self.view.bounds];
authBrowser.delegate = self;
authBrowser.scalesPageToFit = YES;
[self.view addSubview:authBrowser];
NSString *authLink = #"http://api.vk.com/oauth/authorize?client_id=-&scope=audio&redirect_uri=http://api.vk.com/blank.html&display=touch&response_type=token";
NSURL *url = [NSURL URLWithString:authLink];
[authBrowser loadRequest:[NSURLRequest requestWithURL:url]];
}
- (void) webViewDidFinishLoad:(UIWebView *)authBrowser
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Lol" message:#"OLOLO" delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil, nil];
[alert show];
}
#end
So, if i'm commeting delegate string - everything working fine, but I didn't recieve my webViewDidFinishLoad event.
What I'm doing wrong?
The error isn't in the code you have posted. Your zombie message is saying your reference to vkLogin is bad. So you need to look at whatever class creates and holds a reference to your vkLogin class.
That class should be doing something like a vkLogin *foo = [[vkLogin alloc] init];
Update:
Based on your comments it looks like you are creating a local variable for vkLogin. It would be most useful to see the code creates and uses vkLogin and how it's called. Barring that, here are a few guesses.
You are called the method which creates and adds vkLogin to a subView more than once. (Each time would create a new instance).
You have some sort of call back which can occur after vkLogin has been removed.
My guess is vkLogin should be a property in your class, not a local method variable.
in your .h you would add
#proprerty (strong, nonatomic) vkLogin *vk;
and in your .m file you could refer to it as self.vk so you'd create it and add it as a subview like:
self.vk = [[vkLogin alloc] init];
[self.view addSubview:self.vk];
On a side note, convention says we should start class names with a capital letter, so you'd name the class VkLogin which would make it easily distinguishable from a variable named vkLogin (but worry about that after you solve the problem)

Login to web services

I am currently stuck on the part where user use his username and password to view his data. I did try every piece of information on this website to find out how to make it work with no luck so far if anyone can point me in the right direction I'll be grateful.
here is my .h file:
#import <UIKit/UIKit.h>
#interface ePaymentLoginViewController : UIViewController {
IBOutlet UITextField *__weak usernameField;
IBOutlet UITextField *__weak passwordField;
IBOutlet UIButton *__weak loginButton;
IBOutlet UIActivityIndicatorView *__weak loginIndicator;
}
#property (weak, nonatomic) UITextField *usernameField;
#property (weak, nonatomic) UITextField *passwordField;
#property (weak, nonatomic) UIButton *loginButton;
#property (weak, nonatomic) UIActivityIndicatorView *loginIndicator;
- (IBAction) login: (id) sender;
- (IBAction)backButton:(id)sender;
- (IBAction)cancelButton:(id)sender;
#end
here is my .m file:
#import "ePaymentLoginViewController.h"
#interface ePaymentLoginViewController ()
#end
#implementation ePaymentLoginViewController
#synthesize usernameField;
#synthesize passwordField;
#synthesize loginButton;
#synthesize loginIndicator;
- (IBAction) login: (id) sender
{
NSString *post =[NSString stringWithFormat:#"%#/%#",usernameField.text, passwordField.text];
NSString *hostStr = #"http://ourserver/mobilepay/MobilePayService.svc/verify/%#/%#";
hostStr = [hostStr stringByAppendingString:post];
NSData *dataURL = [NSData dataWithContentsOfURL: [ NSURL URLWithString: hostStr ]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
if([serverOutput isEqualToString:#"text/json"]){
UIAlertView *alertsuccess = [[UIAlertView alloc] initWithTitle:#"Congrats" message:#"You are authorized" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alertsuccess show];
} else {
UIAlertView *alertsuccess = [[UIAlertView alloc] initWithTitle:#"Login Failed" message:#"Username or Password Incorrect" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alertsuccess show];
loginIndicator.hidden = TRUE;
loginButton.enabled = TRUE;
[loginIndicator startAnimating];
}
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn’t have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren’t in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(IBAction)backButton:(id)sender{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)cancelButton:(id)sender{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
after successful login this is how the url should look and it will send JSON data
http://ourserver/mobilepay/MobilePayService.svc/verify/user123/test123
{
"Table": [
{
"comp_filenum": 1006842,
"comp_namar": "username123",
"comp_civid": "100000"
}
],
"Table1": [
{
"tran_num": 30301,
"inst_val": 1725,
"balance": 3450,
"late_amount": 3450,
"late_inst_no": 2,
"legal_status": 0,
"baloon_balance": 0,
"late_bal_no": 0,
"remain_bal_no": 0,
"clienttype": 2,
"filenumber": 1006842,
"customername": "username123",
"civilid": "100000",
"saleprice": 82800,
"costprice": 66005,
"last_receiptnumber": "e22512",
"last_paydate": "2012-05-02T00:00:00",
"last_payamount": 1725,
"paidamount": 79350,
"remaininginstallment": 16
},
So what am i doing wrong at this point and what is the right way to do it.
Try with below line :
NSString *hostStr = [NSString stringWithFormat:#"http://ourserver/mobilepay/MobilePayService.svc/verify/%#/%#",usernameField.text, passwordField.text];
NSURL *aURL = [NSURL URLWithString: hostStr];
NSLog(#"%#",aURL); // check the log
NSData *dataURL = [NSData dataWithContentsOfURL:aURL];
Try to show the value of hostStr
NSString *post =[NSString stringWithFormat:#"%#/%#",usernameField.text, passwordField.text];
NSString *hostStr = #"http://ourserver/mobilepay/MobilePayService.svc/verify/%#/%#";
hostStr = [hostStr stringByAppendingString:post];
It will show :
http://ourserver/mobilepay/MobilePayService.svc/verify/%#/%#username/password
Try with this :
NSString *hostStr = #"http://ourserver/mobilepay/MobilePayService.svc/verify/%#/%#";
NSString *url = [NSString stringWithFormat:hostStr,usernameField.text, passwordField.text];

EXC_BAD_ACCESS questions

I am making a poetry app in which users can write your poems and save them to a file. When I click on the UITextView to add and edit text it instantly causes a EXC_BAD_ACCESS. Can somebody please help me as to why this is happening.
This is what I have in the .h file
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController {
UITextView *newPoemTextView;
UIImageView *newPoemTextViewBackground;
}
#property (nonatomic, retain) IBOutlet UITextView *newPoemTextView;
#property (nonatomic, retain) IBOutlet UIImageView *newPoemTextViewBackground;
-(IBAction)closeKeyboard;
#end
and this is what I have in the .m file
#implementation SecondViewController
#synthesize newPoemTextView;
#synthesize newPoemTextViewBackground;
-(IBAction)closeKeyboard {
// This part will write the information to the file
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentTXTPath = [documentsDirectory stringByAppendingPathComponent:#"savedText.txt"];
NSString *savedString = newPoemTextView.text;
[savedString writeToFile:documentTXTPath atomically:YES];
//This part hopefully closes the keyboard correctly, cross fingers
[newPoemTextView resignFirstResponder];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
UIImage *image = [UIImage imageNamed: #"newPoemBackground.png"];
[newPoemTextViewBackground setImage:image];
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage
imageNamed:#"background.png"]];
self.view.backgroundColor = background;
[background release];
[super viewDidLoad];
}
You should synthesize both the property in SecondViewController.m file.
#synthesize newPoemTextView;
#synthesize newPoemTextViewBackground;
You should also implement Keyboard's all method, that will help you a lot.