Unable to show UIAlertView - iphone

in my app i am using validation keys to download content from a server using Wi-Fi. I need to show a UIAlert if the licence keys are wrong or if the wi-fi is not available. I have written the coed for displaying the alert view but the alert is not being displayed... This is scking the blood out my head... Can anyone help please....the control is going over this line, but still the alert is not being displayed.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory= [[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory]; //[pathToStore objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingFormat:#"packages"];
NSString *packagePath = [NSString stringWithFormat:#"%#/%#", path,isbnTemp];
[recievedData writeToFile:[documentsDirectory stringByAppendingPathComponent:#"file.zip"] atomically:YES];
NSString *zipPath=[documentsDirectory stringByAppendingPathComponent:#"file.zip"];
[fileManager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:NO attributes:nil error:nil];
ZipArchive *zipArchive = [[ZipArchive alloc]init];
if([zipArchive UnzipOpenFile:zipPath]){
if([zipArchive UnzipFileTo:packagePath overWrite:YES]){
[self loadContent];
}
else{
NSLog(#"Unable to UnArchieve the packages");
}
}
else {
NSLog(#"Failure To Open Archive");
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Your ISBN and/or Licence Key are incorrect" message:Nil delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
}

Are you trying to show the UIAlertView in a method that is being called from a thread other than the main thread? For example, if you are trying to show the UIAlertView in an asynchronous callback, it could be running on a separate thread.
If so, you need to move the code that shows the UIAlertView to a separate selector, and call it on the main thread using one of the performSelectorOnMainThread: methods.
For example, add the following method to your class:
-(void)showAlert {
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Your ISBN and/or Licence Key are incorrect" message:Nil delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
And then change the last else clause in your current code so that it uses:
[self performSelectorOnMainThread:#selector(showAlert) withObject:nil waitUntilDone:NO];
See the NSObject class reference for more information on the performSelectorOnMainThread: methods.

After you've created the alert could you check for a NULL pointer in the alert variable?
Maybe you need to specify a message? Other than that I can't see anything wrong with the code you've posted.

Related

how to call a storyboard scene conditionally from a button

I have an application who's first scene is a login screen. On pressing the login button, if the username and password are correct, the next scene should get called. Otherwise an alert is shown. But I am unable to figure out how to get the next scene conditionally.
if ([jsonDict valueForKey:#"success"] && [jsonDict valueForKey:#"redirect"]) {
NSLog(#"%#", [jsonDict valueForKey:#"success"]);
NSLog(#"%#", [jsonDict valueForKey:#"redirect"]);
NSString *redirect = [jsonDict valueForKey:#"redirect"];
[self performSegueWithIdentifier:#"next" sender:self];
}
else {
NSArray *jsonArray = [jsonDict valueForKey:#"errors"];
NSString *err = [jsonArray objectAtIndex:0];
NSLog(#"%#", err);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Invalid Credentials!" message:err delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
Set up a Segue to the next viewcontroller in your storyboard and give that segue a unique identifier. Then, if username and password are ok, just call
[self performSegueWithIdentifier:#"yourSegueIdentifier" sender:self];
Use below code:
- (void)validateLogin{
//code to check username and password are correct
if(correct){
[self performSegueWithIdentifier:#"SignInToNextScreen" sender:self];
}else{
UIAlertView *myalert = [[UIAlertView alloc]initWithTitle:#"Login Failed" message:#"Invalid Username/Password" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
}
}
//SignInToNextScreen is a segue identifier for manually triggered segue.
Please see the attached screen shot

UIAlertView on main queue crashing.

I have an issue showing a UIAlertView on the main thread. I'm not sure why but it keeps crashing, despite me running on the main thread. The following block is on the background thread, but I have the alert on the main as below:
void (^removeFromCalendar)(NSString *, NSString *, EKEventStore *) = ^(NSString *error, NSString *eventKey, EKEventStore *eventDB) {
EKEvent *myEvent = [eventDB eventWithIdentifier:eventKey];
NSError *err = noErr;
if(myEvent != NULL && myEvent != (id)[NSNull null]) {
[eventDB removeEvent:myEvent span:EKSpanThisEvent error:&err];
} else {
// Event was not found, nothing to do
return;
}
[eventDB release];
if (!err || err == noErr) {
NSLog(#"Deleted event %#", myEvent.title);
// Show alert on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Showing the alert for unattending
NSString *resultString = #"This event was removed from your calendar.";
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Info" message:resultString delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil] autorelease];
[alert show];
});
return;
}
error = err.description;
};
If I comment out the bottom where it shows the alert, everything is fine. But for the alert, I keep getting a EXC_BAD_ACCESS error. Can somebody explain why? It's on the correct thread, and I cant for the life of me understand where the memory issue could come from!
May be you view is being released when you finish until you finish with the background queue. So, for safety why dont you use it like this;
...........
UIViewController __weak *myController = self;
dispathch_async(backgroundQueue, ^{
UIViewController __strong *myStrongController = myController;
...............
dispatch_async(dispatch_get_main_queue(), ^{
if(myStrongController){
// Showing the alert for unattending
NSString *resultString = #"This event was removed from your calendar.";
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Info" message:resultString delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil] autorelease];
[alert show];
}
});
}).
This is how you present an alert view:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"<#(NSString *)#>" message:#"<#(NSString *)#>" delegate:self cancelButtonTitle:#"<#(NSString *)#>" otherButtonTitles:nil];
[alert show];
[alert release];
Instead of using dispatch_async, why not use the objective C call:
[self performSelectorOnMainThread
You might have to package it up in its own method. Alternatively, call it using:
[self performSelector:#selector(myAlertMethod) withObject:nil afterDelay:0.25]
These methods have been tried and true since day 1.

Downloading files from uiwebview in iphone sdk

Is there any way to download file from UIWebView i am using this code on my IBAction event
- (IBAction)saveFile:(id)sender {
// Get the URL of the loaded ressource
NSURL *theRessourcesURL = [[self.webDisplay request] URL];
NSString *fileExtension = [theRessourcesURL pathExtension];
if ([fileExtension isEqualToString:#"png"] || [fileExtension isEqualToString:#"jpg"] ||
[fileExtension isEqualToString:#"pdf"] || [fileExtension isEqualToString:#"html"]) {
// Get the filename of the loaded ressource form the UIWebView's request URL
NSString *filename = [theRessourcesURL lastPathComponent];
NSLog(#"Filename: %#", filename);
// Get the path to the App's Documents directory
NSString *docPath = [self documentsDirectoryPath];
// Combine the filename and the path to the documents dir into the full path
NSString *pathToDownloadTo = [NSString stringWithFormat:#"%#/%#", docPath, filename];
// Load the file from the remote server
NSData *tmp = [NSData dataWithContentsOfURL:theRessourcesURL];
// Save the loaded data if loaded successfully
if (tmp != nil) {
NSError *error = nil;
// Write the contents of our tmp object into a file
[tmp writeToFile:pathToDownloadTo options:NSDataWritingAtomic error:&error];
if (error != nil) {
NSLog(#"Failed to save the file: %#", [error description]);
} else {
// Display an UIAlertView that shows the users we saved the file :)
UIAlertView *filenameAlert = [[UIAlertView alloc] initWithTitle:#"File saved" message:[NSString stringWithFormat:#"The file %# has been saved.", filename] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[filenameAlert show];
[filenameAlert release];
}
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning"
message:#"File could not be loaded"
delegate:nil
cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
[alert release];
// File could notbe loaded -> handle errors
}
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Warning"
message:#"File type not supported"
delegate:nil
cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
[alert release];
// File type not supported
}
}
this code open the file in UIWebView , which i want to download and when i press the button the opened file get save.
But i want my UIWebView to behave like normal browser , when the download link appear in it and user press it, UIWebView show dialog with option open it or save it if user press save the file get save automatically and if user press open it file should open in UIWebView.
You can provide webView:shouldStartLoadWithRequest in your UIWebViewDelegate so that each time the user is about to move to another web page, you have the chance to check what the link looks like:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[[request URL] scheme] isEqual:#"http"] &&
[[[request URL] pathExtension]...])
<your download/save code here>
return NO; //-- no need to follow the link
}
return YES; //-- otherwise, follow the link
}

UIActionSheet isn't loading actions for button indexes?

I have set up some code so that when two separate buttons are tapped on a UIActionSheet, there will be two different actions. Unfortunately nothing happens when the buttons are pressed. The UIActionSheet just unloads as if a cancel button had been pressed.
Here's my code:
- (IBAction)saveFile:(id)sender {
UIActionSheet *saveFileSheet = [[[UIActionSheet alloc]
initWithTitle:#"iDHSB Download Centre"
delegate:nil
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Download File", #"Show My Files", nil]
autorelease];
[saveFileSheet showInView:webView];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(#"Action Sheet Button Pressed");
if(buttonIndex == 1) {
NSLog(#"Show My Files");
[self.window presentModalViewController:savedFiles animated:YES];
}
if(buttonIndex == 2){
NSLog(#"Saving File");
// Get the URL of the loaded ressource
NSURL *theResourcesURL = [[webView request] URL];
// Get the filename of the loaded ressource form the UIWebView's request URL
NSString *filename = [theResourcesURL lastPathComponent];
NSLog(#"Filename: %#", filename);
// Get the path to the App's Documents directory
NSString *docPath = [self documentsDirectoryPath];
// Combine the filename and the path to the documents dir into the full path
NSString *pathToDownloadTo = [NSString stringWithFormat:#"%#/%#", docPath, filename];
// Load the file from the remote server
NSData *tmp = [NSData dataWithContentsOfURL:theResourcesURL];
// Save the loaded data if loaded successfully
if (tmp != nil) {
NSError *error = nil;
// Write the contents of our tmp object into a file
[tmp writeToFile:pathToDownloadTo options:NSDataWritingAtomic error:&error];
if (error != nil) {
UIAlertView *filenameErrorAlert = [[UIAlertView alloc] initWithTitle:#"Error Saving" message:[NSString stringWithFormat:#"The file %# could not be saved. Please try again.", filename] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[filenameErrorAlert show];
[filenameErrorAlert release];
NSLog(#"Failed to save the file: %#", [error description]);
} else {
// Display an UIAlertView that shows the users we saved the file :)
UIAlertView *filenameAlert = [[UIAlertView alloc] initWithTitle:#"File saved" message:[NSString stringWithFormat:#"The file %# has been saved.", filename] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[filenameAlert show];
[filenameAlert release];
}
} else {
NSLog(#"Error, file could not be saved");
}
}
else
{
NSLog(#"Error, could not find button index!");
}
}
Thanks,
James
You have set the UIActionSheet delegate to nil. In this context, you want to set it to self.
You have to set the delegate to self
UIActionSheet *saveFileSheet = [[[UIActionSheet alloc]
initWithTitle:#"iDHSB Download Centre"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Download File", #"Show My Files", nil]
autorelease];
You’re creating the action sheet with a nil delegate, so the delegate methods you implemented will never get called. Pass self as the delegate in the action sheet’s initializer and it should work.

Knowing when a file has uploaded to Dropbox

I have managed to get my app to upload to Dropbox like so:
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
[self.restClient uploadFile:#"ZipTest.zip" toPath:[NSString stringWithFormat:#"/%#", self.dropboxFolderName] fromPath:docsPath];
But am now trying to verify it actually completed the upload. I know I can check for errors but how to check for completion?
I have tried using:`- (void)restClient:(DBRestClient*)client uploadProgress:(CGFloat)progress forFile:(NSString *)destPath from:(NSString *)srcPath {
Buut all I get is the number 1 printed even though I see on Dropbox the file has not completed the upload yet?
any ideas?
Thanks`
- (void)restClient:(DBRestClient *)client uploadedFile:(NSString *)srcPath {
NSString *filename = [[srcPath pathComponents]lastObject];
NSString *message = [NSString stringWithFormat:#"Uploaded File:%#",filename];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Success"
message:message delegate:nil cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}
I used this code to check file is uploaded or not and after uploading this alert will show