Local Notifications which update their content - ios6

Code:
-(void)viewWillDisappear:(BOOL)animated
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay: 3];
[components setMonth: 7];
[components setYear: 2012];
[components setHour: 21];
[components setMinute: 21];
[components setSecond: 30];
[calendar setTimeZone: [NSTimeZone defaultTimeZone]];
NSDate *dateToFire = [calendar dateFromComponents:components];
UILocalNotification *noti =[[UILocalNotification alloc] init];
noti.fireDate = dateToFire;
noti.repeatInterval = kCFCalendarUnitDay;
noti.soundName = #"chun.aiff";
noti.alertBody = [NSString stringWithFormat:#"Personal balance: %i", -PB];
[[UIApplication sharedApplication] scheduleLocalNotification:noti];
}
The flaw:
If I'm right, I'd say that once this local notification is "embedded" into the device's memory, it sticks with every local notification which has been created. I'm I right? If this is true, how can I manage this situation?

The notification alert is being repeated because you have used:
noti.repeatInterval = kCFCalendarUnitDay;
Your notification alert is scheduled only for the date you set using date to fire, but the alert is repeated on a day interval as you have set.
Set it to nil if you don't want it to repeat.
Hope it solves your problem.
:)

Related

Convert a NSString to a NSDate

I have a NSString like this 05/09/2015 then I want to convert it into this format 2014-07-28 18:30:00 +0000
that second date was the one that I get from the system date. That date can be placed nicely on Tapku calender. but my string is the first one. I want to convert that 1st date just like as the date format that im getting from the system date. How can I do that.
Please help me. Thanks
NSString to NSDate
NSString *dateString = #"01-02-2010";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// this is imporant - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];
// voila!
dateFromString = [dateFormatter dateFromString:dateString];
NSDateFormatter *otherFormatter = [[NSDateFormatter alloc] init];
[otherFormatter setDateFormat:#"yyyy-MM-dd"];
//[otherFormatter setTimeStyle:NSDateFormatterMediumStyle];
NSString *resultString = [otherFormatter stringFromDate:dateFromString];
NSLog(#"%#", resultString);
And then you can convert it back to an NSDate or keep as an NSString.
See this: Click Here

How to use NSMutableDictionary in an UIAlertView?

I am making a calorie counter and I have created an UIAlertView which gives me list of food items. I have made a NSMutableDictionary containing the food and the calories:
#implementation FoodDatabase
-(id)init
{
self = [super init];
if(self)
{
food= [[NSMutableDictionary alloc] init];
[food setObject:#"111" forKey:#"Rice"];
}
return self;
}
-(NSString *) foodList: (NSString *) foodItem
{
for(NSString *key in [food allKeys])
{
if([foodItem isEqual: key])
{
NSLog(#"%#",foodItem);
return [food objectForKey:foodItem];
}
}
}
#end
In another class, I have created an UIAlertView which gives a list of food items. This is the code snippet for the item Rice:
NSString *buttonTitle = [alertView buttonTitleAtIndex:buttonIndex];
if([buttonTitle isEqualToString:#"Rice"])
{
NSString *xyz = [foodData foodList: #"Rice"];
food_calorie = ([xyz floatValue]);
UIAlertView *rice_alert=[[UIAlertView alloc] initWithTitle:#"Enter quantity of rice consumed" message:#"100 gms = 111 calories" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[rice_alert addTextFieldWithValue:#"" label:#"Enter quantity in gms"];
RiceText = [rice_alert textFieldAtIndex:0];
RiceText.keyboardType = UIKeyboardTypeNumberPad;
RiceText.clearsOnBeginEditing = YES;
RiceText.clearButtonMode = UITextFieldViewModeWhileEditing;
RiceText.keyboardAppearance = UIKeyboardAppearanceAlert;
rice_alert.tag = RiceAlertView;
[rice_alert show];
[rice_alert release];
}
I calculate the total calories by using the value entered by the user in the _RiceText_ and the value of the _object_ returned for a specific key (in this case rice). But it seems not to be returning the value of the _object_ as the NSLog shows _(null)_ for the value of _xyz_. Where am I going wrong??
The whole error is that the object foodData isn't initialized properly. So, initialize it
A nice documentation - https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSObject_Class/Reference/Reference.html
& fetching data from NSmutableDictionary
https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDictionary/objectForKey:
Remember the key that you use to compare in dictionary should have same casing (capital - small) as defined earlier. e.g You store an object for key 'example' but you can not retrieve it using ''Example' or 'EXAMPLE'. You can only use 'example' as defined earlier. And
You don't need to get arrays of keys from dictionary & fast-enumerate it
You can just get the object using objectForKey: method. Good luck.

Paypal Sandbox is not working for Non-US developers using Paypal iOS SDK

In my iOS app , I have integrated the adaptive payment using paypal sdk from https://www.x.com/developers/paypal/documentation-tools/paypal-sdk-index
After paypal changed their site , I am not able to perform transaction using above library.
Here is my code
-(void)processSplitPaymentWithFacebuyAdminPayPalId:(NSString*)adminId sellerPayPalId:(NSString*)sellerId withAdminPercentage:(NSNumber*)adminPercentage forTotalAmount:(NSNumber*)totalAmount andShippingCharges:(NSNumber*)shippingCharges
{
NSLog(#"!!!--------------------------------------");
NSLog(#"AdminID: %#",adminId);
NSLog(#"SellerID: %#",sellerId);
NSLog(#"Admin Percentage: %#",adminPercentage);
NSLog(#"Total Amount: %#",totalAmount);
NSLog(#"Shipping Charges: %#",shippingCharges);
NSLog(#"!!!--------------------------------------");
PayPal *ppMEP = [PayPal getPayPalInst];
ppMEP.shippingEnabled = TRUE;
ppMEP.dynamicAmountUpdateEnabled = TRUE;
ppMEP.feePayer = FEEPAYER_EACHRECEIVER;
PayPalAdvancedPayment *payment = [[[PayPalAdvancedPayment alloc] init] autorelease];
payment.paymentCurrency = #"AUD";
payment.receiverPaymentDetails = [NSMutableArray array];
NSArray *emails = [[NSArray alloc]initWithObjects:adminId,sellerId, nil];
for (int i = 0; i < emails.count; i++)
{
PayPalReceiverPaymentDetails *details = [[[PayPalReceiverPaymentDetails
alloc] init] autorelease];
details.invoiceData = [[[PayPalInvoiceData alloc] init] autorelease];
float adminAmount = [adminPercentage floatValue];
float sellerAmount = [totalAmount floatValue] - adminAmount;
switch (i) {
case 0:
// Admin commission
details.subTotal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%f",adminAmount]];
details.description = #"Amount payed to Admin as a Commission";
details.merchantName = [NSString stringWithFormat:#"%#",ADMIN];
break;
case 1:
// Seller amount
details.invoiceData.totalShipping = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%#",shippingCharges]];
details.subTotal = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:#"%f",sellerAmount]];
details.description = #"Amount payed to Seller";
details.merchantName = [NSString stringWithFormat:#"%# : %#",SELLER,#"Seller Name"];
break;
default:
break;
}
details.recipient = [emails objectAtIndex:i];
[payment.receiverPaymentDetails addObject:details];
}
[ppMEP advancedCheckoutWithPayment:payment];
[emails release];
}
But everytime I try to perform the transaction , I get below error
errorId: 580022
message: The receiver is based in a country that isn't enabled to receive payments
My test accounts are created for Australia. My app will be available ONLY in Australia.
Now my question is
1) Does it matter even if my iOS app went in Production ?
2) Also can we use the iOS SDK given in above link or do we need to use latest SDK ?
I saw some links but I am not clear what's going wrong.
Any kind of help is highly appreciated. Thanks.
UPDATE:
If I use US test accounts then still my transaction is not completed.
- (void)paymentFailedWithCorrelationID:(NSString *)correlationID
Above method gets called & here is the response
severity: None
category: Application
errorId: 0
message: None
Here is a screenshot
can you switch over to our new Mobile Payment library for iOS? The old one is now deprecated and everyone is being encouraged to use the new library.
https://developer.paypal.com/webapps/developer/docs/integration/mobile/ios-integration-guide/

iOS 6 Auto Layout Constraints Error: "Something is nil"

I am trying to use constrains in iOS 6 and want to align a label to another. One label and the constrain are created dynamically on a tap on a button. This is a very simple example but i get a wired error and i don't know what's the cause.
The code:
- (IBAction)addToLog:(UIButton *)sender {
UILabel *labelLastTime = [[UILabel alloc]initWithFrame:CGRectMake(20, 359, 92, 42)];
labelLastTime.text = [NSString stringWithFormat:#"%#kg x %#", self.selectedPickerWeight, self.selectedPickerRepetitions];
labelLastTime.font = [UIFont boldSystemFontOfSize:17.0];
labelLastTime.textAlignment = NSTextAlignmentCenter;
labelLastTime.textColor = [UIColor colorWithRed:133.0/255.0 green:133.0/255.0 blue:133.0/255.0 alpha:1.0];
labelLastTime.backgroundColor = [UIColor colorWithRed:228.0/255.0 green:228.0/255.0 blue:228.0/255.0 alpha:1.0];
labelLastTime.layer.borderColor = [UIColor colorWithRed:185.0/255.0 green:185.0/255.0 blue:185.0/255.0 alpha:1.0].CGColor;
labelLastTime.layer.borderWidth = 1;
labelLastTime.layer.cornerRadius = 5;
[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:labelLastTime];
NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:labelLastTime
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.labelTodayVsLastTime
attribute:NSLayoutFormatAlignAllBottom
multiplier:1.0
constant:5.0];
[self.view addConstraint:cn];
}
The Error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to create description in descriptionForLayoutAttribute_layoutItem_coefficient. Something is nil'
The error occurs when i apply the constrain, not when i set it up. I have set a breakpoint just before
[self.view addConstraint:cn]
and when i inspect the result, i get nil values for this 4
container, markerAndPositiveExtraVar, negativeExtraVar and _flange
NSLayoutConstraint *cn = [NSLayoutConstraint constraintWithItem:labelLastTime
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.labelTodayVsLastTime
attribute:NSLayoutFormatAlignAllBottom
multiplier:1.0
constant:5.0];
I had the same problem with a slightly different constraint definition and the cause was an Xcode autocomplete snafu.
Have a look at the second attribute: line. You probably wanted something like attribute: NSLayoutAttributeBottom.
NSLayoutFormatAlignAllBottom is for building an NSLayoutFormatOptions bitmask to be given to something like constraintsWithVisualFormat:options:metrics:views:.

Display dates for a year in a tableview

What I am trying to accomplish here is taking a tableView with a prototype cell, and display the dates in each cell for a year, or two years. I have gotten it to display todays date in the label by using the following code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate *dateNow = [NSDate date];
dateArray = [NSMutableArray arrayWithObjects:[dateFormatter stringFromDate:dateNow], nil];
It works to add one date (todays date) to the first cell. I can not figure out how to get it to add all days by an interval of 1. Any help?
I display the information in the array with this code:
static NSString *CellIdentifier = #"Cell";
Custom *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.dateLabel.text = [dateArray objectAtIndex:indexPath.row];
Here you go,
in the viewDidload,
dateArray = [[NSMutableArray alloc] init]; //dateArray is global
NSDate *thisDate, *nextDate;
thisDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
[dateArray addObject: [dateFormatter stringFromDate:thisDate]];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.day = 1;
for (int i = 0; i<365; i++) //Not considering leap years
{
nextDate = [gregorian dateByAddingComponents:components toDate:thisDate options:0];
[dateArray addObject:[dateFormatter stringFromDate:nextDate]];
thisDate = nextDate;
}
in the cellForRowAtIndexPath
cell.dateLabel.text = [dateArray objectAtIndex:indexPath.row];
You don't need to maintain an array of dates. If you want to display the nth row, you can just add n days to your start date and use that.
So you'd have your start date stored in an instance variable:
NSDate *_startDate;
To determine how many rows should be in the tableView, you have to figure out how many days are in that year (I'm going to assume you're only displaying one year):
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// get the calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
// get the date that points to the first day of the first month of the year containing the start date
// note that we include the era, because some calendars have more than an "AD"/"BC" kind of era
NSDateComponents *yearStartComponents = [calendar components:(NSEraCalendarUnit | NSYearCalendarUnit) fromDate:_startDate];
[yearStartComponents setMonth:1];
[yearStartComponents setDay:1];
NSDate *startOfYear = [calendar dateFromComponents:yearStartComponents];
NSDateComponents *yearDiff = [[NSDateComponents alloc] init];
[yearDiff setYear:1];
// add one year to that date
NSDate *startOfNextYear = [calendar dateByAddingComponents:yearDiff toDate:startOfYear options:0];
// figure out how many days were between the two dates
NSDateComponents *dayDiff = [calendar components:NSDayCalendarUnit fromDate:startOfYear toDate:startOfNextYear options:0];
return [dayDiff day];
}
And then when you need the cell, you can just use the "row" of the indexPath as the number of days from the start date:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = ...;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *diff = [[NSDateComponents alloc] init];
[diff setDay:[indexPath row]];
NSDate *date = [calendar dateByAddingComponents:diff toDate:_startDate options:0];
NSLocale *locale = [NSLocale currentLocale];
NSString *formatted = [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterNoStyle locale:locale];
[[cell textLabel] setText:formatted];
return cell;
}
There are several nice things about this approach:
It works regardless of the length of the year. Whether the current year has 353, 355, 365, 366, or 384 days in the year, it'll work.
It works regardless of the current calendar. There's more than just the Gregorian calendar out there. NSCalendar supports the Gregorian, Buddhist, Chinese, Hebrew, Islamic, Islamic Civil, Japanese, Republic of China, Persian, Indian, and ISO8601 calendars.
You're not hard-coding a format string. By using the NSDateFormatterStyles, you'll be using the appropriate short-hand notation for a date, whether that's "5/12/12" or "5 Dec '12" or something entirely different.

Resources