I want to give my user the option to "share" my apps detailed view page.
Once the user clicks "tweet this" I want the initialText to include a date string ('release_date') that's being parsed with JSON. I'm having trouble displaying the date string in a readable format.
This is how I'm formatting the date (in a NSObject)
- (NSString *) formattedDate {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:self.release_date];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
My release_date is a NSString (this is how the JSON looks)
release_date: "2013-11-16T00:00:00.000Z"
This is how I'm displaying the formattedDate in my detailedViewController
- (void)viewDidLoad
{
[super viewDidLoad];
if([_singleRelease objectForKey:#"release_date"] != NULL)
{
NSString *readableDate = [_singleRelease objectForKey:#"release_date"];
UpcomingRelease *singleRelease = [[UpcomingRelease alloc] init];
singleRelease.release_date = readableDate;
self.release_date.text = [NSString stringWithFormat:#"%#", singleRelease.formattedDate];
}
}
My SLComposeViewController
- (IBAction)shareOnTwitter:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
[tweetSheet setInitialText:[NSString stringWithFormat:#"%# is releasing on %#, via #soleresource", [_singleRelease objectForKey:#"release_name"], [_singleRelease objectForKey:#"release_date"]]];
[self presentViewController:tweetSheet animated:YES completion:nil];
}
}
Thanks
Your code is a bit disorganized. One option would be something like this:
- (NSString *) formattedDate:(NSString *)jsonDateString {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:jsonDateString];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
- (IBAction)shareOnTwitter:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
NSString *formattedDate = [self formattedDate:[_singleRelease objectForKey:#"release_date"]];
[tweetSheet setInitialText:[NSString stringWithFormat:#"%# is releasing on %#, via #soleresource", [_singleRelease objectForKey:#"release_name"], formattedDate]];
[self presentViewController:tweetSheet animated:YES completion:nil];
}
}
Related
I am new to iOS. I am making an alarm application and I want to implement the repeat functionality. I search a lot and didn't understand much how to do this. I know it is done by notification method. I am stuck with it . Please anyone tell me the solution. Here is my code when user save the alarm.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
NSLog(#"dateformater %#",dateFormatter);
dateFormatter.timeStyle = NSDateFormatterShortStyle;
NSString * dateTimeString = [dateFormatter stringFromDate:timePicker.date];
NSLog(#"date time string %#",dateTimeString);
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:NSLocaleIdentifier]];
//[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
datesArray = #[[dateFormatter stringFromDate:self.timePicker.date]];
NSLog(#"dates array is %#",datesArray);
[datesArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
NSArray * repeatDays = [repeatResult componentsSeparatedByString:#","];
for (NSString * days in repeatDays)
{
if ([days isEqualToString:#"Sun"])
{
[self getDateOfSpecificDay:1];
}
if ([days isEqualToString:#"Mon"])
{
[self getDateOfSpecificDay:2];
}
if ([days isEqualToString:#"Tue"])
{
[self getDateOfSpecificDay:3];
}
if ([days isEqualToString:#"Wed"])
{
[self getDateOfSpecificDay:4];
}
if ([days isEqualToString:#"Thu"])
{
[self getDateOfSpecificDay:5];
}
if ([days isEqualToString:#"Fri"])
{
[self getDateOfSpecificDay:6];
}
if ([days isEqualToString:#"Sat"])
{
[self getDateOfSpecificDay:7];
}
}
}];
AlarmObject * alarm = [[AlarmObject alloc] init];
alarm.repeatData = repeatResult;
alarm.clockDate = dateTimeString;
[self.delegate alarmSetting:alarm];
[self scheduleLocalNotificationWithDate:timePicker.date];
[self.navigationController popViewControllerAnimated:YES];
and here is my scheduledLocalNotification mehtod
-(void) scheduleLocalNotificationWithDate:(NSDate *)fireDate
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.alertBody = #"Time to wake Up";
localNotif.alertAction = #"Show me";
localNotif.soundName = #"Tick-tock-sound.mp3";
localNotif.applicationIconBadgeNumber = 1;
localNotif.repeatInterval = NSCalendarUnitWeekOfYear;
NSLog(#"%#",[NSDate date]);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];`
I'm stuck with it from past 4 days. I know my question is duplicate but I am not sure how implement that logic. Thanks in advance.
Change the
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
to
dateFormatter.timeZone = [NSTimeZone localTimeZone];
and check out this tutorial for repeat fucntionailty.
So I'm building a calendar-type app on the new Apple iWatch. This is the initial storyboard layout for my app:
Basically the initial table view will parse the calendar and grab the event name and the date of it. What I want to do is basically, through a push segue, send that data to the second view controller.
I have tried using the method -(NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier, but the context in the second view controller is showing up as nil.
This is my code:
InterfaceViewController:
#import "InterfaceController.h"
#import <EventKit/EventKit.h>
#import "Calendar.h"
#interface InterfaceController() {
NSArray *events;
NSArray *eventsWithNotes;
}
#end
#implementation InterfaceController
- (void)setupTable
{
EKEventStore *store = [[EKEventStore alloc] init];
// Get the appropriate calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
if ([store respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
NSLog(#"User has granted permission!");
// Create the start date components
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
// Create the end date components
NSDateComponents *oneYearFromNowComponents = [[NSDateComponents alloc] init];
oneYearFromNowComponents.year = 1;
NSDate *oneYearFromNow = [calendar dateByAddingComponents:oneYearFromNowComponents
toDate:[NSDate date]
options:0];
// Create the predicate from the event store's instance method
NSPredicate *predicate = [store predicateForEventsWithStartDate:oneDayAgo
endDate:oneYearFromNow
calendars:nil];
// Fetch all events that match the predicate
events = [store eventsMatchingPredicate:predicate];
NSMutableArray *rowTypesList = [NSMutableArray array];
for(int i=0; i < events.count; i++){
[rowTypesList addObject:#"Calendar"];
}
[self.tableView setRowTypes:rowTypesList];
for (NSInteger i = 0; i < self.tableView.numberOfRows; i++)
{
NSObject *row = [self.tableView rowControllerAtIndex:i];
Calendar *calendar = (Calendar *) row;
NSLog(#"notes: %#",[[events objectAtIndex:i] notes]);
NSString* notes = [[events objectAtIndex:i] notes];
[calendar.titleLabel setText:[[events objectAtIndex:i] title]];
}
}
else
{
NSLog(#"User has not granted permission!");
}
}];
}
}
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
// Configure interface objects here.
}
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
[self setupTable];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
NSArray *array = nil;
NSString *notes = [[events objectAtIndex:rowIndex] notes];
NSString *title = [[events objectAtIndex:rowIndex] title];
NSString *strippedNumber = [notes stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [notes length])];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *date = [dateFormatter stringFromDate:[[events objectAtIndex:rowIndex] startDate]];
if([segueIdentifier isEqualToString:#"IBM"]) {
array = #[notes, title, strippedNumber, date];
}
return array;
}
#end
DetailIntefaceViewController.h:
#import <WatchKit/WatchKit.h>
#import <Foundation/Foundation.h>
#interface DetailInterfaceController : WKInterfaceController
#property (nonatomic, strong) NSString *currentContext;
#property (weak, nonatomic) IBOutlet WKInterfaceLabel *phoneNumber;
#end
DetailIntefaceViewController.m:
#import "DetailInterfaceController.h"
#interface DetailInterfaceController ()
#end
#implementation DetailInterfaceController
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
NSLog(#"%#",context);
self.currentContext = context;
// Configure interface objects here.
}
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
NSLog(#"%# willActivate",self.currentContext);
[self.phoneNumber setText:self.currentContext];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
NSLog(#"%# didDeactivate",self.currentContext);
}
#end
Any help would be appreciated.
You don't need that contextsForSegueWithIdentifier method.
After setting up the table, use this method.
- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex
{
NSString *notes = [[events objectAtIndex:rowIndex] notes];
NSString *title = [[events objectAtIndex:rowIndex] title];
NSString *strippedNumber = [notes stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [notes length])];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *date = [dateFormatter stringFromDate:[[events objectAtIndex:rowIndex] startDate]];
//You can push controller instead of segue like this and sending the variable data as a dictionary in context,
[self pushControllerWithName:#"NibIdentifier" context:[NSDictionary dictionaryWithObjectsAndKeys:notes,#"notes",title,#"title",strippedNumber,#"strippedNumber",date,#"date",nil]];
}
Replace "NibIdentifier" with your specific identifier from storyboard.
Retrieve the data in another controller from context using this,
- (void)awakeWithContext:(id)context
{
[super awakeWithContext:context];
NSLog(#"%#",[context objectForKey:#"key1"]);
NSLog(#"%#",[context objectForKey:#"key2"]);
NSLog(#"%#",[context objectForKey:#"key3"]);
NSLog(#"%#",[context objectForKey:#"key4"]);
}
Hi in my application i have a registration form in my application and I'm validating all fields like email and phone number. But i want to validate this DOB in format like DD/MM/YY. I'm using else if condition checking for my validation i want do same for DOB
I'm validation with else if condition like this.
- (IBAction)send:(id)sender {
if ([self phonevalidate:[ph text]]!= 1){
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"Message" message:#"pls enter valid 10 digit number" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[alert1 show];
[alert1 release];
}
else if ([self validateEmail:[emd text]]!= 1){
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"Message" message:#"pls enter valid email id" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil, nil];
[alert1 show];
[alert1 release];
}
My validation function for phone.
-(BOOL)phonevalidate:(NSString *)phh
{
NSString *phoneRegex = #"[0-9]{10}";
NSPredicate *phoneTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", phoneRegex];
return [phoneTest evaluateWithObject:phh];
}
I'm not using the UIDate Picker i have UITextfield for the DOB i want validate with UITextfield itself.Like the above i want to validate the DOB please tell me how to validate the DOB and check int else if condition.
Thanks.
EDITED:
Assume that b'date is
NSString *dateOfBirth = #"22/03/14";
And this is method for check b'date is valid or not ?
-(BOOL) isValidateDOB:(NSString *) dateOfBirth
{
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateStyle:NSDateFormatterShortStyle];
[format setDateFormat:#"dd/MM/yy"];
NSDate *validateDOB = [format dateFromString:dateOfBirth];
if (validateDOB != nil)
return YES;
else
return NO;
}
In above method [format setDateStyle:NSDateFormatterShortStyle]; and setDateFormat is very important in your case:
Now you can check it as like,
if([self isValidateDOB:dateOfBirth])
{
// b"date is valid;
}
else
{
// b"date is not valid;
}
You can use UIDatePicker for this :
Initialize like this :
UIDatePicker datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
datePicker.date = [NSDate date];
Then, set the inputView of your textField (the one that takes DOB as input) :
yourDOBtextField.inputView = datePicker;
Then, implement textFieldDidEndEditing: delegate method for UITextField:
- (void) textFieldDidEndEditing:(UITextField *)textField {
if (textField == yourDOBtextField) {
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"dd/MM/yy";
yourDOBtextField.text = [dateFormatter stringFromDate:datePicker.date];
[dateFormatter release];
}
}
That's it.
Let's try below codes:
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"DD/MM/YY"];
NSDate *date = [dateFormatter dateFromString:#"12/12/2014"];
If (date)
{
NSLog(#"Valid date");
}
Currently I have two NSDateFormatters in my app and I want to somehow "combine" them so I only have, since they're parsing the same date.
I have a NSObject called UpcomingReleases, thats where all my JSON info gets stored.
UpcomingRelease.h
- (NSString *) formattedDate;
UpcomingRelease.m
- (NSString *) formattedDate {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:self.release_date];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
My UICollectionViewController (UpcomingReleasesViewController.m)
if([upcomingReleaseDictionary objectForKey:#"release_date"] != NULL)
{
NSString *readableDate = [upcomingReleaseDictionary objectForKey:#"release_date"];
UpcomingRelease *upcoming = [[UpcomingRelease alloc] init];
upcoming.release_date = readableDate;
cell.release_date.text = [NSString stringWithFormat:#"%#", upcoming.formattedDate];
}
My detailedViewController (ReleaseViewController.m)
(_singleRelease is a NSDictionary)
- (void)viewDidLoad
{
[super viewDidLoad];
if([_singleRelease objectForKey:#"release_date"] != NULL)
{
NSString *readableDate = [_singleRelease objectForKey:#"release_date"];
UpcomingRelease *singleRelease = [[UpcomingRelease alloc] init];
singleRelease.release_date = readableDate;
self.release_date.text = [NSString stringWithFormat:#"%#", singleRelease.formattedDate];
}
}
This was working fine, until I added a share on twitter action and I had to add another NSDateFormatter so it could show the readable date inside the tweet (I would get an error saying "No visible interface for ReleaseViewController declares the selected 'formattedDate'" otherwise).
- (NSString *) formattedDate:(NSString *)jsonDateString {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:jsonDateString];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
#pragma mark - Share on twitter
- (IBAction)shareOnTwitter:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
NSString *formattedDate = [self formattedDate:[_singleRelease objectForKey:#"release_date"]];
[tweetSheet setInitialText:[NSString stringWithFormat:#"%#", formattedDate]];
[self presentViewController:tweetSheet animated:YES completion:nil];
}
}
How can I combine both these NSDateFormatters into one? They're both parsing the same string in the same way (also if there's a better way to show the formattedDate string than the one I'm currently doing would be great).
This is how my JSON shows the date string:
release_date: "2013-11-16T00:00:00.000Z"
Thanks.
As #Hot Licks says:
Make the date formatter a class method:
+ (NSString *) formattedDate:(NSString *)jsonDateString {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *readableDate = [dateFormatter dateFromString:jsonDateString];
[dateFormatter setDateFormat:#"MMMM dd"];
return [dateFormatter stringFromDate:readableDate];
}
Put it in a utility class and use it in both cases. In the first case just pass in self.release_date.
I have the following code block:
NSNumber* dayNsNumber = [[NSNumber alloc] initWithInt:dayNumber+1];
NSLog(#"dayNsNumber: %d", [dayNsNumber intValue]);
if(boolVar){
UIAlertView* success = [[UIAlertView alloc] initWithTitle:#"Title" message:[NSString stringWithFormat:#"Day %d!", dayNumber+1] delegate:self cancelButtonTitle:nil otherButtonTitles:#"Star", nil];
[success show];
NSLog(#"dayNsNumber: %d", [dayNsNumber intValue]);
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
dayNsNumber, "Day Number",
[self getCurrentLocalDate], #"Date",
[self getCurrentLocalTime], #"Time",
nil];
}
What happens is that when I run the code, it hangs upon initialization of the params NSDictionary and says that dayNsNumber is nil.
Xcode displays a Thread 1: EXC_BAD_ACCESS (code=1).
How do I solve thie issue? I would like to add the dayNsNumber to my params dictionary.
Additionally, here are getCurrentLocalDate and getCurrentLocalTime:
-(NSString*)getCurrentLocalDate;{
NSString *formatString = [NSDateFormatter dateFormatFromTemplate:#"dd-MM-yyyy" options:0 locale:[NSLocale currentLocale]];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:formatString];
NSString *todayString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"todayString: \"%#\"", todayString);
return todayString;
}
-(NSString*)getCurrentLocalTime;{
NSString *formatString = [NSDateFormatter dateFormatFromTemplate:#"HH:mm:ss zzz" options:0 locale:[NSLocale currentLocale]];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:formatString];
NSString *timeString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"timeString: \"%#\"", timeString);
return timeString;
}
The problem is with the key: "Day Number" should be #"Day Number".
Also note that you can now use the new syntax for your numbers, arrays, and dictionaries. For example, this
NSNumber* dayNsNumber = [[NSNumber alloc] initWithInt:dayNumber+1];
can be rewritten like this:
NSNumber* dayNsNumber = #(dayNumber+1);
and the dictionary initialization can be done like this:
NSDictionary *params = #{
#"Day Number" : dayNsNumber
, #"Date" : [self getCurrentLocalDate]
, #"Time" : [self getCurrentLocalTime]
};
try this
NSDictionary *params = [[NSDictionary alloc]init];
[params setValue:[daysNumber stringValue] forKey:#"Day Number"];