UILocalNotification getting called repetitively as the app launches - ios

I don't know what is the problem here but everytime I run my app , local notifications get called repetitively showing fireDate as NULL.I am trying to take care of this issue from the past 5hrs now.I need help!!!
"<UIConcreteLocalNotification: 0x7f872ead7630>{fire date = (null), time zone = (null), repeat interval = NSCalendarUnitDay, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Monday, 7 September 2015 5:32:44 pm India Standard Time, user info = (null)}",
I have done enough research on UILocalNotification to get started with it,but i'm still facing this problem.
-(void)setDate:(NSDate*)myfireDate andTime1InString: (NSString*)time1Str andTime2InString:(NSString*)time2Str andTime3InString:(NSString*)time3Str{
//concatenate myFireDate with all three times one by one
NSString *myFireDateInString = [dateFormatter stringFromDate:myfireDate];
myFireDateInString = [myFireDateInString stringByAppendingString:#" "];
NSString *dateWithTime1InString = [myFireDateInString stringByAppendingString:time1Str];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *dateWithTime1 = [dateFormatter dateFromString:dateWithTime1InString];
NSString *mySecondFireDateInString;
NSString *dateWithTime2InString;
NSDate *dateWithTime2;
if ([time2Str length] !=0){
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
mySecondFireDateInString = [dateFormatter stringFromDate:myfireDate];
mySecondFireDateInString = [mySecondFireDateInString stringByAppendingString:#" "];
dateWithTime2InString = [mySecondFireDateInString stringByAppendingString:time2Str];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
dateWithTime2 = [dateFormatter dateFromString:dateWithTime2InString];
}
NSString *myThirdFireDateInString;
NSString *dateWithTime3InString;
NSDate *dateWithTime3;
if ([time3Str length]!=0){
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
myThirdFireDateInString = [dateFormatter stringFromDate:myfireDate];
myThirdFireDateInString = [myThirdFireDateInString stringByAppendingString:#" "];
dateWithTime3InString = [myThirdFireDateInString stringByAppendingString:time3Str];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
dateWithTime3 = [dateFormatter dateFromString:dateWithTime3InString];
}
NSLog(#"%#",dateWithTime3);
NSLog(#"%#",dateWithTime2);
//block starts here
void(^notificationBlock)(void) = ^{
appDelegate.localNotification1 = [UILocalNotification new];
appDelegate.localNotification1.fireDate = dateWithTime1;
appDelegate.localNotification1.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
if(dateWithTime2 != nil){//Make a new UILocalNotification object
appDelegate.localNotification2 = [UILocalNotification new];
appDelegate.localNotification2.fireDate = dateWithTime2;
appDelegate.localNotification2.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
}
if(dateWithTime3 !=nil){//MAke a new UILocalNotification object
appDelegate.localNotification3 = [UILocalNotification new];
appDelegate.localNotification3.fireDate = dateWithTime3;
appDelegate.localNotification3.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
}
if([_repeatDaysTextField.text isEqualToString:#"Everyday"]){
// appDelegate.localNotification1.alertBody = #"Time to take your medicine";
appDelegate.localNotification1.repeatInterval = kCFCalendarUnitDay;
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification1];
if(dateWithTime2 != nil){
appDelegate.localNotification2.repeatInterval = kCFCalendarUnitDay;
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification2];
appDelegate.localNotification2.alertBody = #"Not2";
NSLog(#"%#",appDelegate.localNotification2);
}
NSLog(#"%#",[NSString stringWithFormat:#"%#",dateWithTime3 ]);
if(dateWithTime3 != nil){
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification3];
}
}
else if([_repeatDaysTextField.text isEqualToString:#"Alternately"]){
}
else if([_repeatDaysTextField.text isEqualToString:#"Weekly"]){
appDelegate.localNotification1.repeatInterval = kCFCalendarUnitWeekday;
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification1];
if(dateWithTime2!=nil){
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification2];
}
if(dateWithTime3!=nil){
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification3];
}
}
else if([_repeatDaysTextField.text isEqualToString:#"Bi-Weekly"]){
}
else if([_repeatDaysTextField.text isEqualToString:#"Monthly"]){
appDelegate.localNotification1.repeatInterval = kCFCalendarUnitMonth;
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification1];
if(dateWithTime2!=nil){
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification2];
}
if(dateWithTime3!=nil){
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification3];
}
}
else if([_repeatDaysTextField.text isEqualToString:#"Yearly"]){
appDelegate.localNotification1.repeatInterval = kCFCalendarUnitYear;
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification1];
if(dateWithTime2!=nil){
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification2];
}
if(dateWithTime3!=nil){
[[UIApplication sharedApplication]scheduleLocalNotification:appDelegate.localNotification3];
}
}
};
//block ends here
//method to set notification
[self setNotification:notificationBlock];
}
-(void)setNotification:(void(^)(void))setNotificationBlock{
setNotificationBlock();
}

I got the solution.In the method,didReceiveLocalNotification:,I was adding the notification object to the 'scheduledNotifications' array.So every time a notification was scheduled,the same object was being added to the 'scheduledNotifications' array and that was getting fired again and again.
[UIApplication sharedApplication]scheduledNotifications = notification;
NOTE:Ignore this statement in didReceiveLocalNotification:

This is occuring beacuse you are setting
appDelegate.localNotification.repeatInterval = someUnit;
try setting the repeatInterval value to 1 by checking whether the repeatCount is 0 or not.

Related

How to know call has been made from my application in objective c?

I am new to iOS so pardon me when i make mistake. i want call a person from my application and i wrote these code for that :-
- (IBAction)onClickCallIcon:(id)sender {
NSString *phoneNumber =_lblLeadMobileNumber.text;
NSURL *phoneUrl = [NSURL URLWithString:[#"telprompt://" stringByAppendingString:phoneNumber]];
NSURL *phoneFallbackUrl = [NSURL URLWithString:[#"tel://" stringByAppendingString:phoneNumber]];
if ([UIApplication.sharedApplication canOpenURL:phoneUrl]){
[UIApplication.sharedApplication openURL:phoneUrl];
} else if ([UIApplication.sharedApplication canOpenURL:phoneFallbackUrl]){
[UIApplication.sharedApplication openURL:phoneFallbackUrl];
}
}
and i want to know, Is call has been made or not? if possible how much length of call. how can achieve it?
You can make Call by:
tel:// try to call direct the phone number
telprompt:// shows you an alert to confirm call
if you want to know the user press Call button or Cancel button then can use completionHandler status for it.
Swift Code:
let phoneNumber = "XXXXXXXXXX" // Your phone number here
if let url = URL(string: "tel://\(phoneNumber)") {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: { (status) in
if status{
print("User Press Call Button")
}else{
print("User Press Cancel Button")
}
})
} else {
// Fallback on earlier versions
}
}
Objective-C Code
NSString *phoneNumber = #"XXXXXXXXXX";
NSURL *phoneUrl = [NSURL URLWithString:[#"tel://" stringByAppendingString:phoneNumber]];
NSDictionary *options = [NSDictionary new];
if ([UIApplication.sharedApplication canOpenURL:phoneUrl])
{
[UIApplication.sharedApplication openURL:phoneUrl options:options completionHandler:^(BOOL success) {
if (success){
NSLog(#"User Press Call Button");
}else{
NSLog(#"User Press Cancel Button");
}
}];
}
For your another question "possible how much length of call", the answer is NO, You can't get Call duration, there is no public API for this.
Refer Screenshot with running code:
Find Attached Running Project
#Anbu.karthik & #Rocky for helping me.
i used allKit/CXCallObserver to observe the call which is the answer of second part of my question and from that part i also get answer of first i.e call is connected or not. by using following code:-
In viewdidload:
CXCallObserver *callObserver = [[CXCallObserver alloc] init];
[callObserver setDelegate:self queue:nil];
self.callObserver = callObserver;
and a method:
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
if (call.isOutgoing == YES && call.hasConnected == NO) {
NSLog(#"CXCallState : Dialing");
}
if (call.isOutgoing == NO && call.hasConnected == NO && call.hasEnded == NO && call != nil) {
NSLog(#"CXCallState : Incoming");
}
if (call.hasConnected == YES && call.hasEnded == NO) {
NSLog(#"CXCallState : Connected");
startDate = [NSDate date];
}
if (call.hasConnected == YES && call.hasEnded == YES){
NSLog(#"********** voice call disconnected **********/n");
endDate = [NSDate date];
NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitSecond
fromDate: startDate toDate: endDate options: 0];
NSInteger second = [components second];
NSLog(#"call duration == %ld",(long)second);
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[formatter setDateFormat:#"MM/dd/yyyy hh:mm:ss"];
NSString *startDateFormatted = [formatter stringFromDate: startDate];
NSString *endDateFormatted = [formatter stringFromDate: endDate];
NSMutableDictionary *Dict = [[NSMutableDictionary alloc] init];
[Dict setValue:startDateFormatted forKey:#"startDate"];
[Dict setValue:endDateFormatted forKey:#"endDate"];
[Dict setValue:[NSString stringWithFormat:#"%ld", (long)second] forKey:#"interval"];
[currentShowingData updateCommunications:Dict];
}
these give me all what i wanted. thanks again who helped me.

How to make register notification in Objective C?

I have an online radio. The radio has programs at different times, programs are displayed in a list.
My need is that when one tap and hold on the list of program he schedule a notification to the User.
examplo program in list:
Tap and hold is already running (code below):
-(void)registerHour:(UILongPressGestureRecognizer *)gestureRecognizer
{
CGPoint ponto = [gestureRecognizer locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:ponto];
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.imageAgendamento.hidden = false;
NSString *test = [ NSString stringWithFormat:#"%#",[[results objectAtIndex:indexPath.row] objectForKey:#"hour" ]];
NSLog(#"hour -> %#", test);
}
}
The test is where has the time of notification "09:00" (in direct
format JSON)
appDelegate.m i add:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
}
Looked at several tutorials and researched in various places, I could not solve my problem any way. What I need to do to get this notification schedule?
You can send a 5 min delayed local notification using the code below:
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
NSDate *currentDate = [NSDate date];
[dateComponents setMinute:5];
NSDate *fireDate = [gregorian dateByAddingComponents:dateComponents toDate:currentDate options:0];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
// Configure the notification
// ....
//
localNotification.fireDate = fireDate;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
But I think what you need to do is using an NSTimer or simply the performSelector:withObject:afterDelay: method of NSObject.

How do I make UILocalNotification method keep running

I am trying to build a calendar style app that reminds people when certain events are happening the day before they happen.
I am using UILocalNotifications for this.
I have to restart my app if I want the notification to appear.
How can I have this code continuously run regardless if the app is still running or is closed, and display the notification on time?
I was wondering if I had to put this into the applicationDidEnterBackground method to make it work?
Currently my code looks like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMMM dd, yyyy"];
NSString* path = [[NSBundle mainBundle] pathForResource:#"example"
ofType:#"txt"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
NSArray* allLinedStrings = [content componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
NSDate *tomorrow = [today dateByAddingTimeInterval:60*60*24*1];
NSString *tomorrowString = [dateFormatter stringFromDate:tomorrow];
for (int i = 0; i < allLinedStrings.count; i++) {
NSString* strsInOneLine = [allLinedStrings objectAtIndex:i];
NSArray* singleStrs = [strsInOneLine componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#";"]];
NSString *date = [singleStrs objectAtIndex:0];
if ([date isEqualToString:tomorrowString]) {
for (int j = 1; j < singleStrs.count; j+=2) {
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.fireDate = [NSDate dateWithTimeInterval:60*60*-24 sinceDate:tomorrow];
notification.alertBody = [singleStrs objectAtIndex:j+1];
notification.alertTitle = [singleStrs objectAtIndex:j];
notification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication]scheduleLocalNotification:notification];
}
}
}
// Override point for customization after application launch.
return YES;
}
Your app code does not need to be running for your local notification to be displayed. Once your app has called scheduleLocalNotification:, the notification will display whether or not you app is running.
If you app is in the foreground, you will also want to implement application:didReceiveLocalNotification:. If you want your app to respond to being opened by the user interacting with the notification, you will want to implement application:handleActionWithIdentifier:forLocalNotification:completionHandler:
As to the question of where to put the code that schedules the notification, it should go anywhere in your app that knows the event to be scheduled. It only needs to be called once per notification. It can be scheduled far in advance.

Handle Foursquare hours API to find out if the venue is opened or closed

I have a foursquare hours array (Foursquare API) that stores segments of hours when a specific venue is open. It looks something like this:
[{
"days":[1,2,3,4,7],
"includesToday":true,
"open":[
{"end":"+0200","start":"1000"}],
"segments":[]},
{
"days":[5,6]
,"open":[
{"end":"+0300","start":"1000"}],
"segments":[]}
]
How do I find out if the venue is opened or closed at current time?
I handle it like this: 4sq hours API gist
-(NSDictionary*)isVenueOpenDictionaryForHours:(NSArray*)hours{
// defaults and inits
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDictionary *lastSegmentYesterday = [[NSDictionary alloc] init];
NSDate *dateNow = [NSDate date];
NSString *venueOpenText = [[NSString alloc] init];
NSString *venueOpen = #"no";
// get components for today
NSDateComponents *compsNow = [gregorian components:NSWeekdayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:dateNow];
// get weekday for today and yesterday so we can lookup 4sq API
NSInteger weekday = [compsNow weekday];
NSInteger weekdayYesterday = (weekday>1)?weekday-1:7;
// look for todays' segment
NSMutableArray *venueOpenSegments = [[NSMutableArray alloc] init]; // stores all the segments when the venue is open
for (NSDictionary *segment in hours){
// get today's segment (if it exists)
if ([segment[#"days"] containsObject:[NSNumber numberWithInteger:weekday]]){
for (NSDictionary *dictOpen in segment[#"open"])
[venueOpenSegments insertObject:#{#"end": [dictOpen[#"end"] mutableCopy], #"start":[dictOpen[#"start"] mutableCopy]}.mutableCopy atIndex:venueOpenSegments.count];
}
// check the day before if the venue is open past midnight
if (([segment[#"days"] containsObject:[NSNumber numberWithInteger:weekdayYesterday]] && [segment[#"open"] count])){
// get the last segment (that should be the one passing midnight)
NSDictionary *tempSegment = [segment[#"open"] lastObject];
// if it has more than 4 characters it's after midnight ("+02:00"), also, ignore if it closes at midnight
if ([tempSegment[#"end"] length] > 4 && ![tempSegment[#"end"]isEqualToString:#"+0000"]){
// create a new segment that starts at midnight and lasts till the time it closes (early AMs usually)
lastSegmentYesterday = #{#"start":#"0000", #"end":[tempSegment[#"end"] substringFromIndex:1]};
}
}
}
// add last night segment that passes midnight as the first segment of today
if (lastSegmentYesterday.count){
[venueOpenSegments insertObject:lastSegmentYesterday atIndex:0];
}
// go through all the segments and find out if the venue is closed or open
if (venueOpenSegments.count){
NSDateComponents *comps = [[NSDateComponents alloc] init];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc]init];
timeFormatter.dateFormat = #"HH:mm"; // set time output format
int segmentNumber = 0;
for (NSMutableDictionary *segment in venueOpenSegments){
segmentNumber++;
// confing start date
[comps setDay:compsNow.day];
[comps setMonth:compsNow.month];
[comps setYear:compsNow.year];
[comps setHour:[[segment[#"start"] substringToIndex:2] intValue]];
[comps setMinute:[[segment[#"start"] substringFromIndex:2] intValue]];
NSDate *dateStart = [[[NSCalendar currentCalendar] dateFromComponents:comps] copy];
// config end date
// check if the segment goes to next day
BOOL closesTomorrow = NO;
if ( [segment[#"end"] length]==5 ){
segment[#"end"] = [segment[#"end"] substringFromIndex:1];
closesTomorrow = YES;
}
[comps setHour:[[segment[#"end"] substringToIndex:2] intValue]];
[comps setMinute:[[segment[#"end"] substringFromIndex:2] intValue]];
NSDate *dateEnd = [[[NSCalendar currentCalendar] dateFromComponents:comps] copy];
// add a day if it closes tomorrow
if (closesTomorrow){
NSDateComponents *nextDayComponent = [[NSDateComponents alloc] init];
nextDayComponent.day = 1;
dateEnd = [gregorian dateByAddingComponents:nextDayComponent toDate:dateEnd options:0];
}
// start checking if it's open or closed
// now < segment start
if ([dateNow compare:dateStart] == NSOrderedAscending){
venueOpenText = [NSString stringWithFormat:#"opens at %#",[timeFormatter stringFromDate: dateStart]];
venueOpen = #"later";
break;
}
// segment end < now
else if ([dateEnd compare:dateNow] == NSOrderedAscending){
if (segmentNumber == venueOpenSegments.count){
venueOpenText = [NSString stringWithFormat:#"closed since %#",[timeFormatter stringFromDate: dateEnd]];
break;
}
continue;
}
// segment start < now < segment end
else if ([dateStart compare:dateNow] == NSOrderedAscending && [dateNow compare:dateEnd] == NSOrderedAscending){
venueOpenText = [NSString stringWithFormat:#"open till %#",[timeFormatter stringFromDate: dateEnd]];
venueOpen = #"yes";
break;
}
// rare but possible... last minute of the venue being open (I treat it as closed)
else {
venueOpenText = #"closing right now";
}
}
}
else venueOpen = #"closed today"; // no segments for today, so it's closed for the dayƦ
// return results
return #{#"open":venueOpen, #"string":venueOpenText};
}
and I update my UILabel like this:
NSDictionary *venueOpen = [self isVenueOpenDictionaryForHours:_arrayVenues[indexPath.row][#"hours"]];
label.text = venueOpen[#"string"];
if ([venueOpen[#"open"] isEqualToString:#"no"]){
label.textColor = [UIColor colorWithHexString:#"b91d47" alpha:1]; // red
} else if ([venueOpen[#"open"] isEqualToString:#"yes"]) {
label.textColor = [UIColor colorWithHexString:#"1e7145" alpha:1]; // green
} else if ([venueOpen[#"open"] isEqualToString:#"later"]) {
label.textColor = [UIColor colorWithHexString:#"e3a21a" alpha:1]; // yellow
}
BTW, I use pod 'HexColors' for colorWithHexString methods

Local Notification Ever Changing Text

I am working on getting local notifications to fire at a time every day (set by the user). I have done this in the past, but just where it was one static message that would get shown every day. I would like for it to take the text for the local notification from a plist file I have made with each row being a quote. Is there a way to fire local notifications, but have it change the text every day?
I have right now:
- (IBAction)scheduleNotification {
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil) {
UILocalNotification *notif = [[cls alloc] init];
notif.fireDate = [datePicker date];
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Today's 5 Minutes With God Study Is Now Available";
notif.alertAction = #"Ok";
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = 1;
NSInteger index = [scheduleControl selectedSegmentIndex];
switch (index) {
case 0:
notif.repeatInterval = NSDayCalendarUnit;
break;
case 1:
notif.repeatInterval = 0;
break;
}
NSDictionary *userDict = [NSDictionary dictionaryWithObject:#"Today's Quote!"
forKey:kRemindMeNotificationDataKey];
notif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
[self.notifications addObject:notif];
[notif release];
}
}
So, how would I get the alertBody to show a different message each day?
You have to create a new notification every time, for every new message.

Resources