I am attempting to save an event into the calendar, from my application.
My code works for iOS 7, but on iOS 6, it returns No calendar has been set.
The application prompts for user to grant access to the calendar, on iOS 7.
But no such prompt appears for iOS 6. Although the application is granted access in the Settings-> Privacy -> Calendar.
And yes, I have already implemented the requestAccessToEntityType:completion:.
Here is my code snippet.
EKEventStore *objStore = [[EKEventStore alloc]init];
if ([objStore respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
// iOS 6 and later
[objStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if (granted)
{
// code here for when the user allows your app to access the calendar
EKEvent *calEvent = [EKEvent eventWithEventStore:objStore];
calEvent.title = mstrTitleEvent;
calEvent.startDate = self.dateToBeSet;
calEvent.endDate = self.dateToBeSet;
calEvent.calendar = objStore.defaultCalendarForNewEvents;
EKAlarm *objAlarm = [EKAlarm alarmWithAbsoluteDate:self.dateToBeSet];
[calEvent addAlarm:objAlarm];
NSError *error;
BOOL _bStatus = [objStore saveEvent:calEvent span:EKSpanThisEvent commit:YES error:&error];
UIAlertView *alertV;
if(_bStatus)
{
alertV = [[UIAlertView alloc]initWithTitle:#"Congratulations" message:#"Saved To Calendar" delegate:nil cancelButtonTitle:#"Right On!" otherButtonTitles:nil];
[alertV show];
}
else
{
alertV = [[UIAlertView alloc]initWithTitle:#"Alert" message:[NSString stringWithFormat:#"Error saving to calendar, with error %#.",[error localizedDescription]] delegate:nil cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alertV show];
}
}
else
{
// code here for when the user does NOT allow your app to access the calendar
UIAlertView *alertV = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"Please grant access to the calendar, and try again later." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alertV show];
}
});
}];
}
Just managed to somehow find a solution for my problem.
I had to navigate from one page to another, so posting the link to the two pages.
First ->
https://discussions.apple.com/message/16497282#16497282
Then, from there to ->
https://discussions.apple.com/message/16479587#16479587
I had to go into Settings>iCloud> and turn on Calendars.
After that, I tried to attempt and run my code, and it was working well and fine again.
Do attempt this, if you facing a similar problem.
I was working on iPad 2, and with iOS 6.1.3 installed on the device.
Amazing I am testing my code on two different devices, one it works fine and the other it will not work. Just looked in setting and the one with it not working has iCloud calendar and reminders turned off, just turn them on and it all works now... this has to be a bug
Related
I am trying to add a user (HMUser) to my home (HMHome) by
[self.home addUserWithCompletionHandler:^(HMUser *user, NSError *error) {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
return;
}
NSLog(#"add done!");
[weakSelf.tableView reloadData];
}];
as referenced from: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/HomeKitDeveloperGuide/ManagingUsers/ManagingUsers.html
From my phone (whose iCloud email is: me#gmail.com for e.g.), I add a guest (whose iCloud email is: guest#gmail.com for e.g.). Immediately, the guest receives a notification from Apple and has to press Accept, as expected. After that, my app can display the guest email, which is correct. The issue is: the guest is very hard to view my shared home. Sometimes I have to wait ~ 2 hours but the guest still cannot view my home layout. I tried to reset wifi/bluetooth on the guest phone but things are not better.
Do you have any ideas about this issue on how to fix it?
Thanks in advance,
I'm making an iOS application (Obj-c) with a login form. I'm trying to figure out if there is a way to use Touch ID to login. This will be an amazing feature for my app, but I can't find a way to do it.
In the last PayPal update they include the Touch ID login - so there is a way to do it.
EDIT: I know how to get if the user enter the correct Touch ID, but I don't know what to do after that.
What if the user enter his username and then add the Touch ID correctly? How could I know this user have this Touch ID?
Okay first create an action like so:
We need more detail tough, as I do not know if you mean Obj-C or swift, I'll just post both.
Obj-C
Firstly import the local authentication framework
#import <LocalAuthentication/LocalAuthentication.h>
Then we create an IBAction and add the following code:
- (IBAction)authenticateButtonTapped:(id)sender {
LAContext *context = [[LAContext alloc] init];
NSError *error = nil;
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:#"Are you the device owner?"
reply:^(BOOL success, NSError *error) {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"There was a problem verifying your identity."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
return;
}
if (success) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Success"
message:#"You are the device owner!"
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"You are not the device owner."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
}];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Your device cannot authenticate using TouchID."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
}
The just connect your IBAction to a button that will prompt authentication.
However in Swift you would use:
Add the following framework to your project: LocalAuthentication
Then import it in your swift file:
import LocalAuthentication
Then create the following method that will prompt you to use touch id:
func authenticateUser() {
// Get the local authentication context.
let context = LAContext()
// Declare a NSError variable.
var error: NSError?
// Set the reason string that will appear on the authentication alert.
var reasonString = "Authentication is needed to access your notes."
// Check if the device can evaluate the policy.
if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error) {
[context .evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: NSError?) -> Void in
if success {
}
else{
// If authentication failed then show a message to the console with a short description.
// In case that the error is a user fallback, then show the password alert view.
println(evalPolicyError?.localizedDescription)
switch evalPolicyError!.code {
case LAError.SystemCancel.rawValue():
println("Authentication was cancelled by the system")
case LAError.UserCancel.rawValue():
println("Authentication was cancelled by the user")
case LAError.UserFallback.rawValue():
println("User selected to enter custom password")
self.showPasswordAlert()
default:
println("Authentication failed")
self.showPasswordAlert()
}
}
})]
}
else{
// If the security policy cannot be evaluated then show a short message depending on the error.
switch error!.code{
case LAError.TouchIDNotEnrolled.rawValue():
println("TouchID is not enrolled")
case LAError.PasscodeNotSet.rawValue():
println("A passcode has not been set")
default:
// The LAError.TouchIDNotAvailable case.
println("TouchID not available")
}
// Optionally the error description can be displayed on the console.
println(error?.localizedDescription)
// Show the custom alert view to allow users to enter the password.
self.showPasswordAlert()
}
}
Lastly from the func viewDidLoad call the function like so: authenticateUser()
Hope that helps. Keep coding.
Sources:
Swift:
App Coda iOS 8 Touch ID Api
Objective-C:
tutPlus iOS Touch ID
Thanks to Matt Logan for the updated swift code.
I think I understand what I have to do!
After the first user Login I'll save his password (at NSUserdefaults for example).
If the user want to use his Touch ID at the next login - I'll ask him for the Touch ID and if it's correct i'll let him in with the password saved at the beginning.
Thanks to Julian :)
I'm trying to show an alert from my app. When my app is successfully connected with zebra printer and then if the printer doesnot have paper at the time of printing.. i want to show an alert in my app about the paper out error... please sunbmit your answers if anybody knows...
What exactly you are looking for? Do you want to know the code for how to create and show an alert? or do you want to interact with printer and get the status so as to show alert?
If you are looking for code that shows an alert here you go..
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Printer Warning" message:#"Printer running out of paper" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
have u used this block?
void (^completionhandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *print, BOOL completed, NSError *error)
{
if (!completed && error)
{
NSLog(#"%#", error.localisedDescription);
}
};
if any error occurs, the error will be logged and u can also use it in AlertView.
if(!completed && error)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.localisedDescription cancelButtonTitle:nil otherButtons:#"OK", nil];
[alertview show];
}
Using Parse (iOS framework), I am able to sign up and login successfully using two API.
When user log in, it will cache the user and so accessing "currentUser" will return appropriate object. But sign up API is not caching.
Is there any way that sign up itself will cache the user and avoid separate log in functionality?
It should automatically log you in as well. For example, if in your completion block in signUpInBackground, you have a segue to your main screen and in your main screen, it is supposed to show information related to the user, then it will because [PFUser currentUser] is set to the user that registered.
here is an example
[user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[[error userInfo] objectForKey:#"error"] message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok", nil];
[alertView show];
// Bring the keyboard back up, because they'll probably need to change something.
[_usernameField becomeFirstResponder];
}
else{
// Success!
[self performSegueWithIdentifier:#"goToMain" sender:self];
}
}];
I am simply wanting to add an event to the device's calendar.
I'm using:
__weak ProgramViewController *weakSelf = self;
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (error)
NSLog(#"EKEventStore error = %#", error);
if (granted)
{
NSLog(#"EKEvent *event ");
EKEvent *event = [EKEvent eventWithEventStore:store];
event.title = weakSelf.program.title;
event.location = weakSelf.program.locationPublic;
event.startDate = weakSelf.program.startTime;
event.endDate = weakSelf.program.endTime;
[event setCalendar:[store defaultCalendarForNewEvents]];
NSError *err = nil;
[store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
if (err)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Calendar Error" message:err.localizedDescription delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Added" message:#"Calendar event added." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
}
}];
and in iOS 6 it can take 6/7 seconds (iPhone 4) and on iOS 7 (on an iPhone 5S) it takes ~10 seconds. Is this normal behaviour? If not what am I doing wrong?
I had the same issue. Thanks to Jasper's answer, I got thinking about queues. Try this:
if (!err)
{
dispatch_async(dispatch_get_main_queue(),
^{
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"event added", nil) message:nil delegate:nil cancelButtonTitle:NSLocalizedString(#"ok", nil) otherButtonTitles:nil] show];
});
}
Here's why this is needed (see emphasis)
Discussion
In iOS 6 and later, requesting access to an event store
asynchronously prompts your users for permission to use their data.
The user is only prompted the first time your app requests access to
an entity type; any subsequent instantiations of EKEventStore uses
existing permissions. When the user taps to grant or deny access, the
completion handler will be called on an arbitrary queue. Your app is
not blocked while the user decides to grant or deny permission.
Since UIAlertView is UIKit, and UIKit always requires the main thread, any other arbitrary thread will crash or lead to unpredictable behaviour.
https://developer.apple.com/library/ios/documentation/EventKit/Reference/EKEventStoreClassRef/Reference/Reference.html
According to the docs: "An EKEventStore object requires a relatively large amount of time to initialize and release." . . so you should dispatch this on a background queue.
Also, oddly, it takes longer on the main queue than the background queue - not sure why this is!