CMStepCounter not providing step count - ios

I'm trying to explore CoreMotion and I'm trying to use CMStepCounter class to get the Step counts. here is how I implemented my view controller to get stepCounts
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *stepsCountingLabel;
#property (nonatomic, strong) CMStepCounter *cmStepCounter;
#property (nonatomic, strong) NSOperationQueue *operationQueue;
#end
#implementation ViewController
- (NSOperationQueue *)operationQueue
{
if (_operationQueue == nil)
{
_operationQueue = [NSOperationQueue new];
}
return _operationQueue;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if ([CMStepCounter isStepCountingAvailable])
{
self.cmStepCounter = [[CMStepCounter alloc] init];
[self.cmStepCounter startStepCountingUpdatesToQueue:self.operationQueue updateOn:1 withHandler:^(NSInteger numberOfSteps, NSDate *timestamp, NSError *error)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self updateStepCounterLabelWithStepCounter:numberOfSteps];
}];
}];
}
else
{
self.stepsCountingLabel.text = #"NO STEP COUNTING AVAILABLE";
}
}
- (void)updateStepCounterLabelWithStepCounter:(NSInteger)countedSteps
{
self.stepsCountingLabel.text = [NSString stringWithFormat:#"%ld", (long)countedSteps];
}
But when I walk carrying device, I'm not getting any update but when I shake device It gives me some random numberOfSteps count. Please do let me know if I'm missing out something.

Try below method. I think it will work .Call startStepCalculations method from viewdidload..I am calculating steps for 1 day.
- (void)startStepCalculations {
if (!self.stepCounter) {
self.stepCounter = [[CMStepCounter alloc] init];
}
if (![CMStepCounter isStepCountingAvailable]) {
return;
}
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:(NSHourCalendarUnit |
NSMinuteCalendarUnit |
NSSecondCalendarUnit)
fromDate:[[NSDate alloc] init]];
[components setHour:-[components hour]];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
NSDate *start = [cal dateByAddingComponents:components toDate:[[NSDate alloc] init] options:0];
[components setHour:+24];
[components setMinute:0];
[components setSecond:0];
NSDate *end = [cal dateByAddingComponents:components toDate:start options:0];
NSOperationQueue *queue = [NSOperationQueue mainQueue];
[self.stepCounter queryStepCountStartingFrom:start
to:end
toQueue:queue
withHandler:^(NSInteger numberOfSteps, NSError *error) {
if (error) {
NSLog(#"ERROR : %#",error.localizedDescription);
return;
}
self.steps = numberOfSteps;
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:self.steps];
[self beginMonitoringForNewSteps];
}];
}
- (void)beginMonitoringForNewSteps {
if (!self.stepCounter) {
self.stepCounter = [[CMStepCounter alloc] init];
}
NSOperationQueue *queue = [NSOperationQueue mainQueue];
[self.stepCounter startStepCountingUpdatesToQueue:queue
updateOn:1
withHandler:^(NSInteger numberOfSteps, NSDate *timestamp, NSError *error) {
// calculate the total steps (today + new)
self.steps += (int)numberOfSteps;
//TODO badge number should be 1000 max
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:self.steps];
}];
}
Let me know it is working or not.
Happy Coding!!!

Related

Message from debugger: Terminated due to signal 9

im trying to create an event from my app, to add it to the calendar, im using the code below:
- (IBAction)refreshTapped:(id)sender {
// [self performSegueWithIdentifier:#"calendarsegue" sender:nil];
EKEventStore *store = [[EKEventStore alloc] init];
if([store respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
// iOS 6
[store requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self createEventAndPresentViewController:store];
});
}
}];
} else
{
// iOS 5
[self createEventAndPresentViewController:store];
}
}
- (void)createEventAndPresentViewController:(EKEventStore *)store
{
EKEvent *event = [self findOrCreateEvent:store];
EKEventEditViewController *controller = [[EKEventEditViewController alloc] init];
controller.event = event;
controller.eventStore = store;
controller.editViewDelegate = self;
[self presentViewController:controller animated:YES completion:nil];
}
- (EKEvent *)findOrCreateEvent:(EKEventStore *)store
{
NSString *title = #"My event title";
// try to find an event
EKEvent *event = [self findEventWithTitle:title inEventStore:store];
// if found, use it
if (event)
return event;
// if not, let's create new event
event = [EKEvent eventWithEventStore:store];
event.title = title;
event.notes = #"";
// event.location = #"Lebanon";
event.calendar = [store defaultCalendarForNewEvents];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.hour = 4;
event.startDate = [calendar dateByAddingComponents:components
toDate:[NSDate date]
options:0];
components.hour = 1;
event.endDate = [calendar dateByAddingComponents:components
toDate:event.startDate
options:0];
return event;
}
- (EKEvent *)findEventWithTitle:(NSString *)title inEventStore:(EKEventStore *)store
{
// Get the appropriate calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
// Create the start range date components
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
// Create the end range date components
NSDateComponents *oneWeekFromNowComponents = [[NSDateComponents alloc] init];
oneWeekFromNowComponents.day = 7;
NSDate *oneWeekFromNow = [calendar dateByAddingComponents:oneWeekFromNowComponents
toDate:[NSDate date]
options:0];
// Create the predicate from the event store's instance method
NSPredicate *predicate = [store predicateForEventsWithStartDate:oneDayAgo
endDate:oneWeekFromNow
calendars:nil];
// Fetch all events that match the predicate
NSArray *events = [store eventsMatchingPredicate:predicate];
for (EKEvent *event in events)
{
if ([title isEqualToString:event.title])
{
return event;
}
}
return nil;
}
- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action
{
[self dismissViewControllerAnimated:YES completion:nil];
// [self fetchCalendarEvents];
}
the event page is opening normally, but when i want to enter the location by keyboard, the app is crashing and giving me the error above in the title enter image description here
Anyone knows where the error is?thanks

Performing Core Data Operations in self created multiple threads to save processing time

I have surfed a lot about performing core data operations in multiple threads but no good luck to solve my problem.
My code is such that I have to download a csv file after every ten minutes which contains each entry of 10 seconds. This file once downloaded is parsed and the contents are saved in database and then files are removed as then, when needed, I can fetch data from database.
Now, I have a huge existing content of more than a month for now which may extend to years also as time passes by, performing this huge task of saving new files to database and fetching objects from core data into an array for already downloaded files using a single thread is causing a huge processing time. Also, views in app needs to be adjusted with all previous data (They are basically plots of quantity vs time).
How can I achieve this in multiple threads and optimize my code processing time and reduce UI Blockage to minimum?
Please note that : Performing the task in background thread is not my concern as I in any case have to show graphs on the basis of total data. Please provide valuable advices.
EDIT: PERFORMED SOME MULTITHREADING
HERE IS THE NEW CODE,
- (void) downloadFiles:(NSString *)dataPath{
__block AppDelegate *appD = (AppDelegate *)[[UIApplication sharedApplication] delegate];
backgroundMOC = [[NSManagedObjectContext alloc] init];
[backgroundMOC setPersistentStoreCoordinator:[[appD managedObjectContext] persistentStoreCoordinator]];
if (parsedDetailsDataArrayForCurrentDay) {
parsedDetailsDataArrayForCurrentDay = nil;
}
if (parsedDetailsDataArrayForCurrentMonth) {
parsedDetailsDataArrayForCurrentMonth = nil;
}
if (parsedDetailsDataArrayForCurrentYear) {
parsedDetailsDataArrayForCurrentYear = nil;
}
parsedDetailsDataArrayForCurrentDay = [[NSMutableArray alloc] init];
parsedDetailsDataArrayForCurrentMonth = [[NSMutableArray alloc] init];
parsedDetailsDataArrayForCurrentYear = [[NSMutableArray alloc] init];
dispatch_group_t d_group = dispatch_group_create();
for (NSInteger i = 0; i <= (self.filesListArray.count - 1); i++) {
NSString *filePathOnPhone = [dataPath stringByAppendingString:[NSString stringWithFormat:#"/%#", [[self.filesListArray objectAtIndex:i] objectForKey:#"kCFFTPResourceName"]]];
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:#"ParsedInfiDetails"];
NSString *nameToGet = [[self.filesListArray objectAtIndex:i] objectForKey:#"kCFFTPResourceName"];
NSLog(#"File Check: %#", nameToGet);
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"fileName = %#", nameToGet];
[fetch setPredicate:predicate];
NSError *error = nil;
NSArray *results = [backgroundMOC executeFetchRequest:fetch error:&error];
NSArray *definedResults = [results copy];
if(definedResults && (definedResults.count !=0)) {
NSLog(#"Entities with that name: %#", results);
#autoreleasepool {
NSArray *result = [[definedResults sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modDate" ascending:YES]]] copy];
NSDate *specificDate = [NSDate date];
NSMutableArray *sortedDateArray = [[NSMutableArray alloc] init];
NSMutableArray *sortedDateCurrentYearArray = [[NSMutableArray alloc] init];
NSMutableArray *sortedDateCurrentMonthArray = [[NSMutableArray alloc] init];
for (int i = 0; i < result.count; i++) {
NSManagedObject *obj = [result objectAtIndex:i];
NSDate *objDate = [obj valueForKey:#"modDate"];
NSCalendar *gregorian = [NSCalendar currentCalendar];
NSDateComponents *components = [gregorian componentsInTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"] fromDate:objDate];
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSDateComponents *specificComps = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:specificDate];
NSInteger specificDay = [specificComps day];
NSInteger specificMonth = [specificComps month];
NSInteger specificYear = [specificComps year];
if(day == 24){
}
if (day == specificDay && month == specificMonth && year == (specificYear-2000)) {
[sortedDateArray addObject:obj];
}
NSDate *todayDate = [NSDate date];
NSDateComponents *componentsForToday = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:todayDate];
NSInteger currentMonth = [componentsForToday month];
NSInteger currentYear = [componentsForToday year];
if (year == (currentYear-2000)) {
[sortedDateCurrentYearArray addObject:obj];
}
if (year == (currentYear -2000) && month == currentMonth) {
[sortedDateCurrentMonthArray addObject:obj];
}
}
NSMutableArray *sortedTimedArray = [[NSMutableArray alloc] initWithArray:[sortedDateArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modTime" ascending:YES]]]];
NSMutableArray *sortedTimedCurrentYearArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentYearArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modTime" ascending:YES]]]];
NSMutableArray *sortedTimedCurrentMonthArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentMonthArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modTime" ascending:YES]]]];
[parsedDetailsDataArrayForCurrentDay addObjectsFromArray:sortedTimedArray];
[parsedDetailsDataArrayForCurrentYear addObjectsFromArray:sortedTimedCurrentYearArray];
[parsedDetailsDataArrayForCurrentMonth addObjectsFromArray:sortedTimedCurrentMonthArray];
}
} else {
NSLog(#"Error: %#", error);
NSString *threadName = [NSString stringWithFormat:#"%ld THREAD", (long)i];
dispatch_queue_t myQueue = dispatch_queue_create([threadName UTF8String], NULL);
dispatch_group_async(d_group, myQueue, ^{
NSManagedObjectContext *backgroundMOC1;
backgroundMOC1 = [[NSManagedObjectContext alloc] init];
[backgroundMOC1 setPersistentStoreCoordinator:[[appD managedObjectContext] persistentStoreCoordinator]];
NSLog(#"Entered Thread ");
BOOL success = [appD.ftpManager downloadFile:[[self.filesListArray objectAtIndex:i] objectForKey:#"kCFFTPResourceName"] toDirectory:[NSURL URLWithString:dataPath] fromServer:srv];
if (success) {
// dispatch_group_async(d_group, myQueue, ^{
NSMutableDictionary *dict = [appD.ftpManager progress];
NSString *filePath = [dataPath stringByAppendingString:[NSString stringWithFormat:#"/%#", [[self.filesListArray objectAtIndex:i] objectForKey:#"kCFFTPResourceName"]]];
CHCSVParser *parser = [[CHCSVParser alloc] initWithContentsOfCSVURL:[NSURL fileURLWithPath:filePath]];
[parser parse];
NSMutableArray *currentFileComponentsArray = [NSArray arrayWithContentsOfCSVURL:[NSURL fileURLWithPath:filePath]];
NSMutableArray *parsedDetailsEntitiesArray = [[NSMutableArray alloc] init];
for (int j = 1; j <= (currentFileComponentsArray.count-1); j++) {
NSArray *detailsArray = [currentFileComponentsArray objectAtIndex:j];
if (!(detailsArray.count < 32)) {
NSManagedObject *parsedDetails = [NSEntityDescription
insertNewObjectForEntityForName:#"ParsedInfiDetails"
inManagedObjectContext:[appD managedObjectContext]];
NSString *totalDateString = [NSString stringWithFormat:#"%# %#", [detailsArray objectAtIndex:0], [detailsArray objectAtIndex:1]];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"dd/MM/yyyy HH:mm:ss";
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[dateFormatter setTimeZone:gmt];
NSDate *startDate = [dateFormatter dateFromString:totalDateString];
[parsedDetails setValue:startDate forKey:#"modDate"];
[parsedDetails setValue:startDate forKey:#"modTime"];
———————————————————————PERFORM PARSEDDETAILS STATEMENTS----------------
NSError *error;
NSLog(#"Saved File in Database: %#", [[self.filesListArray objectAtIndex:i] objectForKey:#"kCFFTPResourceName"]);
NSLog(#"Saved thread");
if (![backgroundMOC1 save:&error]) {
NSLog(#"Whoops, couldn't save: %#", [error localizedDescription]);
}
else{
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
//if the download fails, we try to delete the empty file created by the stream.
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
//when data is stored in coredata remove the downloaded file.
}
[parsedDetailsEntitiesArray addObject:parsedDetails];
}
}
}
NSSet *set = [[NSSet alloc] initWithArray:parsedDetailsEntitiesArray];
[self.relevantInverId setValue:set forKey:#"infiDetails"];
NSDate *specificDate = [NSDate date];
#autoreleasepool {
NSMutableArray *sortedDateArray = [[NSMutableArray alloc] init];
NSMutableArray *sortedDateCurrentYearArray = [[NSMutableArray alloc] init];
NSMutableArray *sortedDateCurrentMonthArray = [[NSMutableArray alloc] init];
for (int i = 0; i < parsedDetailsEntitiesArray.count; i++) {
NSManagedObject *obj = [parsedDetailsEntitiesArray objectAtIndex:i];
NSDate *objDate = [obj valueForKey:#"modDate"];
NSCalendar *gregorian = [NSCalendar currentCalendar];
NSDateComponents *components = [gregorian componentsInTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"] fromDate:objDate];
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSDateComponents *specificComps = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:specificDate];
NSInteger specificDay = [specificComps day];
NSInteger specificMonth = [specificComps month];
NSInteger specificYear = [specificComps year];
if(day == 24){
}
if (day == specificDay && month == specificMonth && year == (specificYear-2000)) {
[sortedDateArray addObject:obj];
}
NSDate *todayDate = [NSDate date];
NSDateComponents *componentsForToday = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:todayDate];
NSInteger currentMonth = [componentsForToday month];
NSInteger currentYear = [componentsForToday year];
if (year == (currentYear-2000)) {
[sortedDateCurrentYearArray addObject:obj];
}
if (year == (currentYear-2000) && month == currentMonth) {
[sortedDateCurrentMonthArray addObject:obj];
}
}
NSMutableArray *sortedTimedArray = [[NSMutableArray alloc] initWithArray:[sortedDateArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modTime" ascending:YES]]]];
[parsedDetailsDataArrayForCurrentDay addObjectsFromArray:sortedTimedArray];
NSMutableArray *sortedTimedCurrentYearArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentYearArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modTime" ascending:YES]]]];
NSMutableArray *sortedTimedCurrentMonthArray = [[NSMutableArray alloc] initWithArray:[sortedDateCurrentMonthArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modTime" ascending:YES]]]];
[parsedDetailsDataArrayForCurrentYear addObjectsFromArray:sortedTimedCurrentYearArray];
[parsedDetailsDataArrayForCurrentMonth addObjectsFromArray:sortedTimedCurrentMonthArray];
}
// });
}
});
}
BOOL isFileAlreadyPresent = [[NSFileManager defaultManager] fileExistsAtPath:filePathOnPhone];
}
NSMutableArray *sortedParsedDetailsArrayForCurrentDay = [[NSMutableArray alloc] initWithArray:[parsedDetailsDataArrayForCurrentDay sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"modTime" ascending:YES]]]];
NSDate *startDate ;
NSDate *endaDate;
dispatch_group_notify(d_group, dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self stopLogoSpin];
[hud dismiss];
});
NSLog(#"All background tasks are done!!");
});
}
Now, logs #"Entered Thread " is visible in log but, #"Saved File in Database: %#", [[self.filesListArray objectAtIndex:i] and #"Saved thread" are not called.
Also,
BOOL success = [appD.ftpManager downloadFile:[[self.filesListArray objectAtIndex:i] objectForKey:#"kCFFTPResourceName"] toDirectory:[NSURL URLWithString:dataPath] fromServer:srv];
helps download file with their seperate thread in the download method.
Should uncommenting below help?
// dispatch_group_async(d_group, myQueue, ^{
Main thread is intentionally made to wait but this block below is also never called:
dispatch_group_notify(d_group, dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self stopLogoSpin];
[radialHUD dismiss];
});
NSLog(#"All background tasks are done!!");
});
Please advice any modification and solution to problems above.
Optimised the code by moving all what is not needed in loop outside and the performing the looping operation using GCD.
dispatch_queue_t myOwnQueue = dispatch_queue_create([#"MyOwnQueue" UTF8String], NULL);
dispatch_apply(self.filesListArray.count, myOwnQueue, ^(size_t i) { });
This lead to reduction in time by half. However any further optimisations need to be seen.

Apple iWatch: contexts not sending between view controllers

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"]);
}

CMStepCounter Adding Number of Steps to Separate NSIntegers

#import "CPPedometerViewController.h"
#import <CoreMotion/CoreMotion.h>
#interface CPPedometerViewController ()
#property (weak, nonatomic) IBOutlet UILabel *stepsCountingLabel;
#property (nonatomic, strong) CMStepCounter *cmStepCounter;
#property (nonatomic, strong) NSOperationQueue *operationQueue;
#property (nonatomic, strong) NSMutableArray *stepsArray;
#end
#implementation CPPedometerViewController
- (NSOperationQueue *)operationQueue
{
if (_operationQueue == nil)
{
_operationQueue = [NSOperationQueue new];
}
return _operationQueue;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self QueryExistingStep];
NSLog( #"steps array = %#", _stepsArray);
}
-(void)QueryExistingStep
{
//get todays date
NSDate *now = [NSDate date];
// get six days ago from today
NSDate *sixDaysAgo = [now dateByAddingTimeInterval:-6*24*60*60];
//array to hold step values
_stepsArray = [[NSMutableArray alloc] initWithCapacity:7];
//check if step counting is avaliable
if ([CMStepCounter isStepCountingAvailable])
{
//init step counter
self.cmStepCounter = [[CMStepCounter alloc] init];
//get seven days before from date & to date.
for (NSDate *toDate = [sixDaysAgo copy]; [toDate compare: now] <= 0;
toDate = [toDate dateByAddingTimeInterval:24 * 60 * 60] ) {
//get day before
NSDate *fromDate = [[toDate copy] dateByAddingTimeInterval: -1 * 24 * 60 * 60];
[self.cmStepCounter queryStepCountStartingFrom:fromDate to:toDate toQueue:self.operationQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
if (!error) {
NSLog(#"queryStepCount returned %ld steps", (long)numberOfSteps);
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self updateArrayWithStepCounter:numberOfSteps];
}];
} else {
NSLog(#"Error occured: %#", error.localizedDescription);
}
}];
}
} else {
// stuffhappens
}
}
- (void)updateArrayWithStepCounter:(NSInteger)numberOfSteps {
[_stepsArray addObject:[NSNumber numberWithInteger:numberOfSteps]];
}
#end
I'm looking to have an array full of steps from the past seven days, and then insert them into to a NSinteger for each day. e.g. NSinteger daySeven = 242, NSInteger daySix = 823 ... etc too today.
However the array seems to clear after exiting the updateArrayWithStepCounter method. Any idea on how i could fix this so each number of steps goes into separate NSIntegers also. Thanks, Ryan.
EDIT:
Here is the NSLog output:
2014-01-25 22:51:36.314 Project[6633:60b] steps array = (
)
2014-01-25 22:51:36.332 Project[6633:420f] queryStepCount returned 3505 steps
2014-01-25 22:51:36.334 Project[6633:420f] queryStepCount returned 3365 steps
2014-01-25 22:51:36.335 Project[6633:420f] queryStepCount returned 7206 steps
2014-01-25 22:51:36.337 Project[6633:420f] queryStepCount returned 6045 steps
2014-01-25 22:51:36.339 Project[6633:420f] queryStepCount returned 5259 steps
2014-01-25 22:51:36.342 Project[6633:420f] queryStepCount returned 6723 steps
2014-01-25 22:51:36.344 Project[6633:420f] queryStepCount returned 440 steps
Here is the output shown as suggested. As you can see its definitely getting the values however when it checks the array after running the method its now empty.
Could i be adding it to the array incorrectly?
I hope this is clearer I'm stumped. Thanks
First, what's the output of this?
NSLog(#"steps array = %#", _stepsArray);
When someone ask you something, you should try to reply with the exact information requested, just saying "it says that array is empty" doesn't help, because maybe someone can see something that you don't see in the output.
Said this, I would add some more NSLog around, because it could be that your handler is not called, or not called with the information that you expect.
Use the following, and let us know the output :)
[self.cmStepCounter queryStepCountStartingFrom:fromDate to:toDate toQueue:self.operationQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
if (!error) {
NSLog(#"queryStepCount returned %d steps", numberOfSteps);
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self updateArrayWithStepCounter:numberOfSteps];
}];
} else {
NSLog(#"Error occured: %#", error.localizedDescription);
}
}];
EDIT: From the new posted output of the NSLog, I can understand the problem. The fact is that the handler runs asynchronously, it means that you can't just output the array on viewDidLoad, because it runs BEFORE the array received all the values, so you should refactor your code to trigger a method when all the data is ready.
Here a revision of your code that is more readable (removed some useless "copy" call, updated your "for conditions", etc...), now it should be really easy to understand what's going on, and how to perform additional logic.
#import "PYViewController.h"
#import <CoreMotion/CoreMotion.h>
#interface PYViewController ()
#property (weak, nonatomic) IBOutlet UILabel *stepsCountingLabel;
#property (nonatomic, strong) CMStepCounter *cmStepCounter;
#property (nonatomic, strong) NSOperationQueue *operationQueue;
#property (nonatomic, strong) NSMutableArray *stepsArray;
#end
#implementation PYViewController
- (NSOperationQueue *)operationQueue {
if (_operationQueue == nil) {
_operationQueue = [NSOperationQueue new];
_operationQueue.maxConcurrentOperationCount = 1; // process 1 operation at a time, or we could end with unexpected results on _stepsArray
}
return _operationQueue;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self queryExistingStep];
}
-(void)queryExistingStep {
// Get now date
NSDate *now = [NSDate date];
// Array to hold step values
_stepsArray = [[NSMutableArray alloc] initWithCapacity:7];
// Check if step counting is avaliable
if ([CMStepCounter isStepCountingAvailable]) {
// Init step counter
self.cmStepCounter = [[CMStepCounter alloc] init];
// Tweak this value as you need (you can also parametrize it)
NSInteger daysBack = 6;
for (NSInteger day = daysBack; day > 0; day--) {
NSDate *fromDate = [now dateByAddingTimeInterval: -day * 24 * 60 * 60];
NSDate *toDate = [fromDate dateByAddingTimeInterval:24 * 60 * 60];
[self.cmStepCounter queryStepCountStartingFrom:fromDate to:toDate toQueue:self.operationQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
if (!error) {
NSLog(#"queryStepCount returned %ld steps", (long)numberOfSteps);
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[_stepsArray addObject:#(numberOfSteps)];
if ( day == 1) { // Just reached the last element, do what you want with the data
NSLog(#"_stepsArray filled with data: %#", _stepsArray);
// [self updateMyUI];
}
}];
} else {
NSLog(#"Error occured: %#", error.localizedDescription);
}
}];
}
} else {
NSLog(#"device not supported");
}
}
#end
What i would do is waiting for the array to get all the needed value and do stuff later. It works for me.
- (void)queryPast6DayStepCounts
{
NSLog(#"queryPast6DayStepCounts visited!");
self.past6DaysDailySteps = [[NSMutableArray alloc] initWithCapacity:6];
// past 6 days
for (NSInteger day = 6; day >= 1; day--)
{
NSDate *fromDate = [self.todayMidnight dateByAddingTimeInterval:-day * 24 * 60 * 60];
NSDate *toDate = [fromDate dateByAddingTimeInterval:24 * 60 * 60];
[self.cmStepCounter
queryStepCountStartingFrom:fromDate to:toDate
toQueue:[NSOperationQueue mainQueue]
withHandler:^(NSInteger numberOfSteps, NSError *error)
{
if (!error)
{
[self.past6DaysDailySteps addObject:#(numberOfSteps)];
if (self.past6DaysDailySteps.count == 6) {
[self viewDidFinishQueryPast6DaysData];
}
}
else
{
NSLog(#"Error occured: %#", error.localizedDescription);
}
}
];
}
}
-(void)viewDidFinishQueryPast6DaysData
{
NSLog(#"queryPast6DayStepCounts finish! %#", self.past6DaysDailySteps);
// do other things
}

EKEvent Get Current Event iOS7

So I need to get the current event in the calendar. I.E - an event that started and did not end yet. I have written some code but it does not work.
Through debugging I noticed my oneDayAgo variable is nil and I do not understand why.
The oneWeekFromNow variable is good.
Here is the method I have written:
-(void)getCurrentEvent{
// Get appropriate calendar
[self.store requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day -=1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
NSDateComponents *oneWeekFromNowComponents = [[NSDateComponents alloc] init];
oneWeekFromNowComponents.week = 1;
NSDate *oneWeekFromNow = [calendar dateByAddingComponents:oneWeekFromNowComponents
toDate:[NSDate date]
options:0];
NSPredicate *predicate = [self.store predicateForEventsWithStartDate:oneDayAgo
endDate:oneWeekFromNow
calendars:nil];
NSMutableArray *currentEvens = [[NSMutableArray alloc]init];
// Fetch all events that match the predicate
[self.store enumerateEventsMatchingPredicate:predicate usingBlock:^(EKEvent *event, BOOL *stop) {
if (([event.startDate compare:[NSDate date]] == NSOrderedDescending) &&
([[NSDate date] compare:event.endDate] == NSOrderedDescending)) {
[currentEvens addObject:event];
}
}];
self.lblEvent.text = [NSString stringWithFormat:#"%#", currentEvens];
[self.view reloadInputViews];
}];
}
Try this instead:
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
Here is the corrected code that worked for me. I also needed to modify some other things:
-(void)getCurrentEvent{
// Get appropriate calendar
[self.store requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *oneDayAgoComponents = [[NSDateComponents alloc] init];
oneDayAgoComponents.day = -1;
NSDate *oneDayAgo = [calendar dateByAddingComponents:oneDayAgoComponents
toDate:[NSDate date]
options:0];
NSDateComponents *oneWeekFromNowComponents = [[NSDateComponents alloc] init];
oneWeekFromNowComponents.week = 1;
NSDate *oneWeekFromNow = [calendar dateByAddingComponents:oneWeekFromNowComponents
toDate:[NSDate date]
options:0];
NSPredicate *predicate = [self.store predicateForEventsWithStartDate:oneDayAgo
endDate:oneWeekFromNow
calendars:nil];
NSMutableArray *currentEvens = [[NSMutableArray alloc]init];
// Fetch all events that match the predicate
[self.store enumerateEventsMatchingPredicate:predicate usingBlock:^(EKEvent *event, BOOL *stop) {
if (([event.startDate compare:[NSDate date]] == NSOrderedAscending) &&
([[NSDate date] compare:event.endDate] == NSOrderedAscending)) {
[currentEvens addObject:event];
}
}];
NSString *currentEventsString = [[NSString alloc]init];
for (EKEvent *event in currentEvens) {
currentEventsString = [currentEventsString stringByAppendingString:event.title];
}
dispatch_async(dispatch_get_main_queue(), ^{
self.lblEvent.text = currentEventsString;
});
}];
}

Resources