MFMailComposeViewController usage and Apple aproval process - iphone

In my app, I have a logs mechanism, which offer the possibility to the customer to send the logs via mail.For this, I integrated in my app the Apple MFMailComposeViewController. In case that the customer use a device with low OS version (2.x) or an e-mail account isn't presented on the device, I pushed some UIAlertsView with some suggestive messages for users. Can somebody please take a look over my below code, and reply if there is something that could lead to a rejection by Apple?
BOOL canSendmail = [MFMailComposeViewController canSendMail];
if (!canSendmail) {
NSMutableString* osVersion = [NSMutableString stringWithString:[[UIDevice currentDevice] systemVersion]];
EventsLog* logs = [EventsLog getInstance];
if ([osVersion characterAtIndex : 0] == '2' || [osVersion characterAtIndex : 0] == '1' ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Email", #"")
message:NSLocalizedString(#"Failed to send E-mail.For this service you need to upgrade the iPhone OS to 3.0 version or later", #"")
delegate:self cancelButtonTitle:NSLocalizedString(#"OK", #"") otherButtonTitles: nil];
[alert show];
[alert release];
[logs writeEvent : #"Cannot send e-mail - iPhone OS needs upgrade to at least 3.0 version" classSource:#"LogsSessionDetailViewController#sendEmail" details : (#" device OS version is %#",osVersion)];
return;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Email", #"")
message:NSLocalizedString(#"Failed to send E-mail.Please set an E-mail account and try again", #"")
delegate:self cancelButtonTitle:NSLocalizedString(#"OK", #"") otherButtonTitles: nil];
[alert show];
[alert release];
[logs writeEvent : #"Cannot send e-mail "
classSource:#"LogsSessionDetailViewController#sendEmail" details : #"- no e-mail account activated"];
return;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Email", #"")
message:NSLocalizedString(#"The data you are sending will be used to improve the application. You are free to add any personal comments in this e-mail", #"")
delegate:self cancelButtonTitle:NSLocalizedString(#"Cancel", #"") otherButtonTitles: nil];
[alert addButtonWithTitle:NSLocalizedString(#"Submit", #"")];
[alert show];
[alert release];
Many thanks,
Alex.

I won't say about appstore admission/rejection but your code must crash on iPhone OS 2.x - you call
BOOL canSendmail = [MFMailComposeViewController canSendMail];
without checking if this call is possible (MFMailComposeViewController class is not available on 2.x system). Also manual checking of OS version is not a good practice. Instead you must at first check if MFMailComposeViewController present in current runtime:
if ( !NSClassFromString(#"MFMailComposeViewController") ){
// Put code that handles OS 2.x version
return;
}
if (![MFMailComposeViewController canSendMail]){
// Put code that handles the case when mail account is not set up
return;
}
//Finally, create and send your log
...
P.S. Do not forget that you must set linkage type for MessageUI framework as 'weak' in target settings - you application will crash on old systems on start if you linkage type will be 'required' (default value).

Related

didFailToRegisterForRemoteNotificationsWithError is fired, how to get more info?

For the first time I am playing with APNS, I tried to run a proof of concept, with an iOS 5.0.1 device, and the didFailToRegisterForRemoteNotificationsWithError is fired. I know it has been fired because I show an UIAlertView to notify the error:
- (void)application:(UIApplication*)application
didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
// Inform the user that registration failed
NSString* failureMessage = #"There was an error while trying to \
register for push notifications.";
UIAlertView* failureAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:failureMessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[failureAlert show];
[failureAlert release];
}
How can I get more info about the error?
Try doing something like NSLog(#"%#", error.userInfo");, that should output some info into the terminal.
I ended up with this code, which works and lets me progress a bit:
NSString* failureMessage = error.localizedDescription;
UIAlertView* failureAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:failureMessage
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[failureAlert show];
Sorry, iObjectiveC noob here.

UIAlertView from Tab Button - No Internet Connection

Looking for some help again...
I've currently got 2 sections of my app that need internet connection, 1 is a photo gallery through Flickr and the other a Twitter Feed, I was wondering if this is the correct code for the UIAlertView... I can get it working from a button but thats all!
{
-(void)didTap_roundedRectButton1:(id)sender forEvent:(UIEvent *)event {
UIAlertView *alertView = [[UIAlertView alloc] init];
alertView.title = #"You are not connected to the Internet!";
alertView.message = #"Please check your connection and try again...";
[alertView addButtonWithTitle:#"Ok"];
[alertView show];
[alertView release];
}
i think you need to use this example as i have used it to check is there any network is available and device is connected to any one of the network it is alos available on the apple's developer example site
example link is this
You should try this:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"You are not connected to the Internet!"
message:#"Please check your connection and try again..."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertView show];
[alertView release];
and can you post the code how do you create the UIButton?

locationManager didFailWithError Repeatedly Called

I am showing alertViews when Location manager unable to find current location. I did it like this
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
[manager stopUpdatingLocation];
switch([error code])
{
case kCLErrorNetwork: // general, network-related error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please check your network connection or that you are not in airplane mode" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
break;
case kCLErrorDenied:{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"User has denied to use current Location " delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
break;
default:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Unknown network error" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
break;
}
}
My problem is locationManager didFailWithError method get called repeatedly. So my alertviews repeatedly display.
How can I solve this issue?
Apple documentation states:
If the location service is unable to retrieve a location right away,
it reports a kCLErrorLocationUnknown error and keeps trying. In such a
situation, you can simply ignore the error and wait for a new event.
If the user denies your application’s use of the location service,
this method reports a kCLErrorDenied error. Upon receiving such an
error, you should stop the location service.
So you might skip some cases where you stop updating and show the alert, especially the default case.
A good start for error messages that can be triggered by an ongoing background process - like the location manager - is to store the reference to the UIAlertView. When the delegate receives alertView:clickedButtonAtIndex:, reset this reference to nil. Before displaying new errors, check if one is already visible.
Even better, don't display modal error messages from background processes. Just walking around, you'll occasionally lose reception, and it's tedious to have to dismiss an error when that happens. If your app has a configuration or help screen, include a space there for the most recent error message from the Location Manager (or Game Center, or iCloud, or anything else that loses connectivity occasionally.)

Reachability Xcode iOS5

i want to add a alter if the user is not connected to the internet and clicks on a webview link.
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Can't connect. Please check your internet Connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
Problem is here:
Void (-) gives error:(!)Invalid argument type 'void' to unary expression
Very possibly the problem does not lie with the -(void)webView:didFailLoadWithError method itself; rather, it seems you are using it in an incorrect way, i.e.. within an expression that requires a unary operator (e.g., negation, increment, etc.).
In other words, it seems you are trying to use the method's return value somewhere, but there is no return value from that method.
Check the code where you call -(void)webView:didFailLoadWithError...
This is very simple you dont have to code in any delegate method for check weather the user is connected to internet,for example the there is a login page for you and the user logs in but network is not connectd ,so we have to give an alert to user that the network is not connectd right?just simply add the
if(responce == nil)ie,responce from the url
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Can't connect. Please check your internet Connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
} else you code

ALAssetsLibrary ALAssetsLibraryAccessUserDeniedError

When you first try to access a user's ALAssetsLibrary, the OS will present them with a dialog asking for permission. If they do not allow this, a failureBlock will be called and will always be called in the future. Is there a way to force a prompt of this authorization request again?
I notice in the Maps app, that they inform the user to go to the Settings app to turn on location services with a button. However, there is no way that I know of to programmatically open the Settings app. Should I just display directions as to how to turn on the location services?
You can't open up the settings app in an Apple approved manner.
The best you can hope for is to trap the error and then display a UIAlertView or other view with instructions on how to do this. Take a look at the latest v. of the Dropbox app for an idea on how they instruct the user.
When you try to access the Library from your code, you can use the error handler to catch the error and display an alert specifying to the user what to do.
Example
failureBlock:^(NSError *error) {
// error handling
if (error.code == ALAssetsLibraryAccessGloballyDeniedError) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:#"Error loading image... \nEnable Location Services in 'Settings -> Location Services'."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[alert show];
} else if (error.code == ALAssetsLibraryAccessUserDeniedError) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:[NSString stringWithFormat:#"Error loading image... \nEnable Location Services in 'Settings -> Location Services' for %#.", [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleDisplayName"]]
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!" message:#"Error loading image..." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}