How can I write a program in Xcode that checks to see if a specific iCal calendar exists and access that calendar in order to add events? - xcode4

I know that the EKEventStore class has the #property NSArray *calendars that returns an array of an event store's calendar objects, however I do not how to access a specific calendar inside of that array when all I know is the calendar's title. The only examples I can find online are of programs that access the defaultCalendarForNewEvents, but the calendar I want is not the default calendar. I also don't know the calendar's unique identifier, all I know is the title. I tried to use a valueForKey method to access the calendar titled BART, but what I am doing is definitely wrong, can anyone help? Here is what i tried:
#interface BARTClass : NSObject {
EKEventStore *eventStore;
EKCalendar *bart
NSArray *calendars;
}
#property (nonatomic, retain) EKEventStore *eventStore;
#property (nonatomic, retain) NSArray *calendars;
#property (nonatomic, retain) EKCalendar *bart;
-(EKCalendar) getBartCalendar;
#end
...
#implementation
#synthesize calendars, bart, eventStore;
-(EKCalendar) getBartCalendar {
[self setEventStore: [[EKEventStore alloc] init]];
[self setCalendars = [eventStore calendars]];
NSArray *titles = [calendars valueForKey:#"title"];
[self setBart:[titles valueForKey:#"BART"]];
...

you are near to the goal, I think.
You can do it like this:
EKEventStore *eventStore = [[EKEventStore alloc]init];
EKCalendar *bart;
NSArray *myCals = [eventStore calendars];
for (int i=0; i < [myCalls count]; i++) {
bart = [myCals objectAtIndex:i];
if (bart.title isEqualToString:#"Bart"){
break;
}
else {
bart = nil;
}
}
If the calendar "Bart" exists, you get it at the end of the loop.

Related

Get date/time for HKQuantitySample -> heartRateSample (Watch OS2) from HealthKit

I am using
-(void)updateHeartRate:(NSArray<__kindof HKSample *> *)samples
to retrieve the HearteRate from the internal watch sensor. Depending on the time the app is in background (deactivated) several heartRateSamples must be retrieved using:
if (samples.count>0) {
for (HKQuantitySample *heartRateSample in samples) {
dispatch_async(dispatch_get_main_queue(), ^{
if (heartRateSample) {
NSLog(#"HEART RATE: %#", [#([heartRateSample.quantity doubleValueForUnit:heartRateUnit]) stringValue]);
}
});
}
}
but how can I retrieve the date/time when the specific sample was written to the HealthKit?
The quantity sample's startDate and endDate properties describe when the sample was taken:
HK_CLASS_AVAILABLE_IOS(8_0)
#interface HKSample : HKObject
#property (readonly, strong) HKSampleType *sampleType;
#property (readonly, strong) NSDate *startDate;
#property (readonly, strong) NSDate *endDate;
#end

Saving an ALAsset to SQLite3 database - retrieve error

I'm trying to save a list of assets to upload in a sqllite3 db, but when i parse the database and set the assets to an array, then try to use the asset i get a SIGABRT error.
ALAsset *asset = (ALAsset *) assets[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"image%d: ready to upload.",indexPath.row];
cell.detailTextLabel.text = #"1.3MB to folder <server folder>";
[[cell imageView] setImage:[UIImage imageWithCGImage:[asset thumbnail]]];// SIGABRT ERROR
Im saving the ALAsset to the database as a string (TEXT) with UTF8formatting
NSMutableArray *tmpArray = [NSMutableArray alloc]init];
///get sql
[tmpArray addObject:someStringFromSQL];
///end sql loop
assets = [tmpArray mutableCopy];
in the code above I tried:
[[cell imageView] setImage:[UIImage imageWithCGImage:[(ALAsset *) asset thumbnail]]];// SIGABRT ERROR
and that didn't work.
This is the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString thumbnail]: unrecognized selector sent to instance 0xc0a7800'
Any suggestions?
Also as a side question: Does anyone know how to get the file size (i.e. 1.3MB) from the asset?
BLOCK:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
//do stuff in cell
NSURL *aURL =[NSURL URLWithString:[assets objectAtIndex:indexPath.row]];
[assetsLibrary assetForURL:aURL resultBlock:^(ALAsset *asset){
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
});
[[NSNotificationCenter defaultCenter] postNotificationName:#"newAssetImageRetrieved" object:nil];
//in this notificaton I'm reloading the data; its putting the tableview in an infinite loop - but the images display...
}
failureBlock:^(NSError *error){
// error handling
NSLog(#"Can't get to assets: FAILED!");
}];
//cell.imageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
cell.textLabel.text = [NSString stringWithFormat:#"image%d: ready to upload.",indexPath.row];
cell.detailTextLabel.text = [NSString stringWithFormat:#"1.3MB to folder %#", [destinations objectAtIndex:indexPath.row]];
//[[cell imageView] setImage:[UIImage imageWithCGImage:[asset thumbnail]]];
return cell;
}
There are a couple of issues with your code sample:
The image retrieval is happening asynchronously, so when you try to update the image, you want to make sure the cell is still visible (and not reused for another NSIndexPath).
In this case, the retrieval from the ALAssetsLibrary will probably be so fast that this isn't critical, but it's a good pattern to familiarize yourself with, because if you're ever retrieving images over the Internet, this issue becomes increasingly important.
Because cells are being reused, if you don't find the image immediately and have to update it asynchronously, make sure you reset the UIImageView before initiating the asynchronous process. Otherwise, you'll see a "flickering" of replacing old images with new ones.
You are using UITableViewCell for your cell. The problem with that is that it will layout the cell based upon the size of the image present by the time cellForRowAtIndexPath finishes.
There are two easy solutions to this. First, you could initialize the cell's imageView to be a placeholder image of the correct size. (I usually have an image called placeholder.png that is all white or all transparent that I add to my project, which is what I used below.) This will ensure that cell will be laid out properly, so that when you asynchronously set the image later, the cell will be laid out properly already.
Second, you could alternatively use a custom cell whose layout is fixed in advance, bypassing this annoyance with the standard UITableViewCell, whose layout is contingent upon the initial image used.
I'd suggest using a NSCache to hold the thumbnails images. That will save you from having to constantly re-retrieve the thumbnail images as you get them from your ALAssetsLibrary as you scroll back and forth. Unfortunately, iOS 7 broke some of the wonderful NSCache memory-pressure logic, so I'd suggest a cache that will respond to memory pressure and purge itself if necessary.
Anyway, putting that all together, you get something like:
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *assetGroups;
#property (nonatomic, strong) ALAssetsLibrary *library;
#property (nonatomic, strong) ThumbnailCache *imageCache;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageCache = [[ThumbnailCache alloc] init];
self.assetGroups = [NSMutableArray array];
self.library = [[ALAssetsLibrary alloc] init];
[self.library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (!group) {
[self.tableView reloadData];
return;
}
CustomAssetGroup *assetGroup = [[CustomAssetGroup alloc] init];
assetGroup.name = [group valueForProperty:ALAssetsGroupPropertyName];
assetGroup.assetURLs = [NSMutableArray array];
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
[assetGroup.assetURLs addObject:[result valueForProperty:ALAssetPropertyAssetURL]];
}
}];
[self.assetGroups addObject:assetGroup];
} failureBlock:^(NSError *error) {
NSLog(#"%s: enumerateGroupsWithTypes error: %#", __PRETTY_FUNCTION__, error);
}];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.assetGroups.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
CustomAssetGroup *group = self.assetGroups[section];
return [group.assetURLs count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
CustomAssetGroup *group = self.assetGroups[section];
return group.name;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
// note, these following three lines are unnecessary if you use cell prototype in Interface Builder
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
CustomAssetGroup *group = self.assetGroups[indexPath.section];
NSURL *url = group.assetURLs[indexPath.row];
NSString *key = [url absoluteString];
UIImage *image = [self.imageCache objectForKey:key];
if (image) {
cell.imageView.image = image;
} else {
UIImage *placeholderImage = [UIImage imageNamed:#"placeholder.png"];
cell.imageView.image = placeholderImage; // initialize this to a placeholder image of the right size
[self.library assetForURL:url resultBlock:^(ALAsset *asset) {
UIImage *image = [UIImage imageWithCGImage:asset.thumbnail]; // note, use thumbnail, not fullResolutionImage or anything like that
[self.imageCache setObject:image forKey:key];
// see if the cell is still visible, and if so, update it
// note, do _not_ use `cell` when updating the cell image, but rather `updateCell` as shown below
UITableViewCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath]; // not to be confused with similarly named table view controller method ... this one checks to see if cell is still visible
if (updateCell) {
[UIView transitionWithView:updateCell.imageView duration:0.1 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
updateCell.imageView.image = image;
updateCell.textLabel.text = asset.defaultRepresentation.filename;
} completion:nil];
}
} failureBlock:^(NSError *error) {
NSLog(#"%s: assetForURL error: %#", __PRETTY_FUNCTION__, error);
}];
}
return cell;
}
#end
The above uses the following classes:
/** Thumbnail cache
*
* This cache optimizes retrieval of old thumbnails. This purges itself
* upon memory pressure and sets a default countLimit.
*/
#interface ThumbnailCache : NSCache
// nothing needed here
#end
#implementation ThumbnailCache
/** Initialize cell
*
* Add observer for UIApplicationDidReceiveMemoryWarningNotification, so it purges itself under memory pressure
*/
- (instancetype)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
self.countLimit = 50;
};
return self;
}
/** Dealloc
*
* Remove observer before removing cache
*/
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
}
#end
and
/** Custom AssetGroup object
*
* This is my model object for keeping track of the name of the group and list of asset URLs.
*/
#interface CustomAssetGroup : NSObject
#property (nonatomic, copy) NSString *name;
#property (nonatomic, strong) NSMutableArray *assetURLs;
#end
#implementation CustomAssetGroup
// nothing needed here
#end
You have to explore all the code base related to the save and retrieve functionality.
However, here are some good tips.
Save the ALAsset Url instead of saving the entire ALAsset as a string.
Retrieve the ALAsset Url from the database and convert it to NSUrlString.
Use ALAsset Library to load the image or thumbnail back.
Hope this will help you.

trouble sending data to detailview

I am using collection view to get data from my server display some of it in a cell and then I have a segue to the destination view controller I got the image to update correctly but for some reason the text is not going to my UITextView
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
//DetailSegue
if ([segue.identifier isEqualToString:#"DetailSegue"]) {
ICBCollectionViewCell *cell = (ICBCollectionViewCell *)sender;
NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
ICBDetailViewController *dvc = (ICBDetailViewController *)[segue destinationViewController];
path = [paths objectAtIndex:indexPath.row];
Path = [path objectForKey:#"path"];
title = [titles objectAtIndex:indexPath.row];
Title = [title objectForKey:#"title"];
sku = [SKUs objectAtIndex:indexPath.row];
Sku = [sku objectForKey:#"SKU"];
longDescrip = [longDescription objectAtIndex:indexPath.row];
LongDescrip = [longDescrip objectForKey:#"longDescrip"];
LongDescrip =#"Hello World";
NSLog(#"Descrip =%#",LongDescrip);
NSString *iconTitle =[NSString stringWithFormat:#"%#.png",Sku];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullPath = [docDir stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#",iconTitle]]; //add our image to the path
dvc.img = [[UIImage alloc] initWithContentsOfFile:fullPath];
dvc.title = Title;
//UITextView *descrip = (UITextView *)[cell viewWithTag:120];
[dvc.descrip setText:#"Hello"];
}
}
I am not sure if it has something to do with the fact that the object being sent to is a UITextView and I am sending it a String
or if I have something hooked up wrong
here is the .m and .h for the detailController also
the .h
#import <UIKit/UIKit.h>
#interface ICBDetailViewController : UIViewController
#property(weak) IBOutlet UIImageView *imageView;
#property (strong) UIImage *img;
#property(weak) IBOutlet UITextView *descrip;
#end
the .m
#import "ICBDetailViewController.h"
#interface ICBDetailViewController ()
#end
#implementation ICBDetailViewController
#synthesize imageView, img, descrip;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView.image = self.img;
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Hopefully somebody will see what I have missed for two days
after again reviewing it all I noticed i missed the outlet in the .h and forgot to set it show in the ViewDidLoad of the .m I also missed hooking upthe referencing outlet to my txtView

Simulator does not show button text

I'm learning to build iPhone apps with XCode 4.5.2 and I noticed something strange. As you can see at the address http://i.stack.imgur.com/purI8.jpg the text inside one of the buttons is not displayed in the iOS6 simulator. I also tried to move the Enter button in the same line of 0 and -, but the text in all three buttons of the line disappeared. Anyone knows what's the cause of this problem and how to solve it? Here is the code:
#import "CalculatorViewController.h"
#import "CalculatorBrain.h"
#interface CalculatorViewController()
#property (nonatomic) BOOL userIsInTheMiddleOfEnteringANumber;
#property (nonatomic, strong) CalculatorBrain *brain;
#end
#implementation CalculatorViewController
#synthesize display;
#synthesize userIsInTheMiddleOfEnteringANumber;
#synthesize brain = _brain;
- (CalculatorBrain *)brain
{
if (!_brain) _brain = [[CalculatorBrain alloc] init];
return _brain;
}
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = [sender currentTitle];
if (self.userIsInTheMiddleOfEnteringANumber) {
self.display.text = [self.display.text stringByAppendingString:digit];
} else {
self.display.text = digit;
self.userIsInTheMiddleOfEnteringANumber = YES;
}
}
- (IBAction)enterPressed
{
[self.brain pushOperand:[self.display.text doubleValue]];
self.userIsInTheMiddleOfEnteringANumber = NO;
}
- (IBAction)operationPressed:(UIButton *)sender
{
if (self.userIsInTheMiddleOfEnteringANumber) [self enterPressed];
NSString *operation = [sender currentTitle];
double result = [self.brain performOperation:operation];
self.display.text = [NSString stringWithFormat:#"%g", result];
}
#end
According to https://developer.apple.com/library/ios/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/doc/uid/TP40006815-CH3-SW7
- (void)setTitle:(NSString *)title forState:(UIControlState)state
To set your button titles.
So in your case:
- (IBAction)operationPressed:(UIButton *)sender{
....
[sender setTitle:[NSString stringWithFormat:#"%g", result] forState: UIControlStateNormal];
// lets assume you want the down states as well:
[sender setTitle:[NSString stringWithFormat:#"%g", result] forState: UIControlStateSelected];
[sender setTitle:[NSString stringWithFormat:#"%g", result] forState: UIControlStateHighlighted];
}

Xcode: Make A Text Field Bring Up A Picker View or Drop Down Menu

Can someone please provide some example code on how I could create the following features on an iOS app:
Option 1:
I want to create a text field through Interface Builder, and when someone clicks on that text field, instead of bringing up the default keyboard, I want it to bring up a Picker View which lists several choices of my liking. Once the user is done picking a certain value, they can click on a "done" button by the picker view and the picker view will go away and the Text Field will be populated with what they chose on the Picker View.
Option 2
If the previous method will require too much code to accomplish, could someone provide example code on how to create a basic Drop Down menu similar to how a standard drop down menu on a website?
Thanks
Create a new file. I called mine AEMPicker. The .h:
#protocol AEMPickerDelegate <NSObject>
-(void)touchedPicker:(NSString *)string;
#optional
-(void)setInitialPickerValueToRow:(int)i inComponent:(int)j animated:(BOOL)k;
#end
#interface AEMPicker : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>{
UIPickerView *pickerView;
}
#property (nonatomic, strong) NSArray *contentArray;
#property (nonatomic, assign) id<AEMPickerDelegate> delegatePicker;
- (id)initWithArray:(NSArray *)contents inFrame:(CGRect)pickerFrame;
#end
the .m:
#import "AEMPicker.h"
#implementation AEMPicker
#synthesize contentArray;
#synthesize delegatePicker;
- (id)initWithArray:(NSArray *)contents inFrame:(CGRect)pickerFrame
{
self = [super init];
if (self) {
contentArray = [NSArray arrayWithArray: contents];
pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.delegate = self;
[self.view addSubview:pickerView];
}
return self;
}
-(void)setInitialPickerValueToRow:(int)i inComponent:(int)j animated:(BOOL)k{
[pickerView selectRow:i inComponent:j animated:k];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
return [contentArray count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [contentArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
[self.delegatePicker touchedPicker:[contentArray objectAtIndex:row]];
}
#end
Now, in the class you want to present your pickerView, after #import AEMPicker; add to your .h:
#interface YourClass : UIViewController <AEMPickerDelegate, UITextFieldDelegate>{
AEMPicker *picker;
UIPopoverController *pickerPopOver;
UIPopoverController *pOC;
CGRect popRect;
}
add to your .m:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[textField resignFirstResponder];
popRect = CGRectMake(406, 110, 0, 0);
CGRect pickerRect = CGRectMake(0, 10, 0, 0);
NSArray *contents = [[NSArray alloc] initWithObjects:#"Object 1", #"Object 2", #"Object 3", nil];
picker = [[AEMPicker alloc] initWithArray:contents inFrame:pickerRect];
picker.delegatePicker = self;
pickerPopOver = [[UIPopoverController alloc] initWithContentViewController:picker];
pickerPopOver.popoverContentSize = CGSizeMake(320, 250);
[pickerPopOver presentPopoverFromRect:popRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:TRUE];
pOC = pickerPopOver;
}
-(void)touchedPicker:(NSString *)string{
[yourTextField setText:string];
[pickerPopOver dismissPopoverAnimated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
[pOC dismissPopoverAnimated:NO];
return YES;
}
That should give you a pretty basic picker popover to play with.

Resources