Adding events to calendar in ios 5 programatically - xcode

eventStore=[[EKEventStore alloc] init];
EKEvent *addEvent=[EKEvent eventWithEventStore:eventStore];
addEvent.title=#"hello";
addEvent.startDate=messageDate;
addEvent.endDate=[addEvent.startDate dateByAddingTimeInterval:600];
[addEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
addEvent.alarms=[NSArray arrayWithObject:[EKAlarm alarmWithAbsoluteDate:addEvent.startDate]];
[eventStore saveEvent:addEvent span:EKSpanThisEvent error:nil];
The code above works fine in ios 4.2 but not in ios 5. I have the code in applicationDidfinishingLaunching method. Due to error, black screen appears and app exits. Only recurrenceRules has changed in ios 5 and I have not made use of it. All other properties are available in superclass EKCalendarItem. I cannot test it since I have xcode 3.2 and snow leopard. I am looking to debug the line at which error occurs causing the app to quit. I doubt it is related to setCalendar or using alarms property.

The code is correct and works in iOS 5. The reason for my error was the first line
eventStore=[[EKEventStore alloc] init];
Since initializing eventstore takes some time, placing it in application launch method resulted in time out. I found it from my crash report stating:
"Elapsed application CPU time (seconds):30 seconds"
The app is supposed to launch within 10 seconds. if not time out occurs with Exception Codes: 0x8badf00d

You have to use 5th version of SDK. You can find a diff in saveEvent function:
[eventStore saveEvent:addEvent span:EKSpanThisEvent commit:YES error:nil];
It should help you.

There was a change (I believe) to the API in iOS5 that requires you to add EKAlarm objects using the addAlarm instance method.
To add an alarm to your event in iOS5:
[addEvent addAlarm:[EKAlarm alarmWithAbsoluteDate:addEvent.startDate]]
Check EKCalendarItem Class Reference for details.
Although #property(nonatomic, copy) NSArray *alarms is not specified as read only it would appear to be behaving that way.
See https://stackoverflow.com/a/7880242/816455 for more information on other iOS5 EKAlarm issues.

NaveenaRK I wasn't having any time out errors however i fixed this by doing the following.
You need to keep the eventStore in memory for the objects life time.
eventStore = [[EKEventStore alloc] init]
I initialised the event store on creating the object and released it in dealloc. The problem with setting the alarms and the "CADObjectGetInlineStringProperty" error were both fixed.

Related

Cocoa - How to detect change in ubiquity container

I've got an OS X app syncing a single document through a ubiquity container back and forth to an iOS equivalent app. The iOS app receives data whenever it changes on the Mac side and sends it whenever it changes on the iOS side (so the iOS app is working all around), and the Mac app sends the data whenever it is changed on the Mac side and it receives the data when the app is launched, but it doesn't seem to be checking again for any data while it runs. I'd like it to update with any changes automatically and immediately, like the OS X "Notes" app does from changes on the iOS side.
At launch, this is the relevant function that gets called:
+(NSMutableDictionary *)getAllNotes {
if(allNotes == nil) {
allNotes = [[NSMutableDictionary alloc]initWithDictionary:[[NSUserDefaults standardUserDefaults] dictionaryForKey:kAllNotes]];
cloudDoc = [[CloudDocument alloc]initWithContentsOfURL:[self notesURL] ofType:NSPlainTextDocumentType error:nil];
[cloudDoc saveToURL:[self notesURL] ofType:NSPlainTextDocumentType forSaveOperation:NSSaveOperation error:nil];
}
return allNotes;
}
and that "CloudDocument" class (which is a subclass of NSDocument) includes:
#import "Data.h"
#implementation CloudDocument
-(NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
return [NSKeyedArchiver archivedDataWithRootObject:[Data getAllNotes]];
}
-(BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
NSDictionary *dict = (NSDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)data];
[Data didReceiveCloudData:dict];
return YES;
}
+(BOOL)autosavesInPlace {
return YES;
}
#end
which kicks it back to:
+(void)didReceiveCloudData:(NSDictionary *)d {
allNotes = [[NSMutableDictionary alloc]initWithDictionary:d];
[[NSUserDefaults standardUserDefaults] setObject:allNotes forKey:kAllNotes];
[cloudDoc updateChangeCount:NSChangeDone];
}
I think the problem is just that I don't have any part of my code that is equivalent to the phrase "check periodically to see if the ubiquity container has changed, and then do..." etc. I'm sure there's a well-known process for this (some notification event in NSDocument or something), but I've searched around and everything I find is either for iOS/UIDocuments instead of OS X/NSDocuments, or it's all theory and over my head without any tangible code samples to comb through and pick apart.
Can anyone help me out with a method for registering that an iCloud document in the ubiquity container has changed, and ideally where to put it (AppDelegate, CloudDocument.m, etc)? I only have one file syncing around, signified by the constant kAllNotes, so I don't need to track a bunch of different files or anything. I'm pretty sure I can use the code that runs at launch to do what needs to be done, I just can't figure out what to do to start the auto-syncing process.
Thank you in advance!
PS I'm still a beginner, so tutorials and code samples are much appreciated.
You're looking for NSMetadataQuery - it does a spotlight-like, continuously running search for any type of file - and is available on both iOS and OS X (indeed on iOS it can only be used for observing changes to the ubiquity container). I don't have any one link on how to use this - the Apple docs are too general to make much sense initially but do a search on 'NSMetadataQuery iCloud' and you should be sorted - there is tons of information out there on this topic.
With NSMetadataQuery you receive a notification every time something in the observed folder system changes, and it's not just applicable to UIDocument files even if a lot of examples are worried about UIDocuments.
Indeed, NSMetadataQuery it is - it feels like a hack but appears to be the only way to monitor changes to standard (non-UIDocument) files.
Here's a sample project I've compiled. It lets you upload an image from the camera roll, then monitors changes to the ubiquitous Documents folder:
https://github.com/versluis/iCloud-Images

How to implement ckrefreshcontrol to support ios5?

I've seen in this question that CKRefreshControl can be used as a substitute for UIRefreshControl for apps that support both iOS5 and iOS6. I've found the code on Github, but I don't know how to implement it. John said to just use the same code. But something is missing. Where does the CKRefreshControl code go?
self.refreshControl = [[UIRefreshControl alloc] init];
Thanks!
There is no specific CKRefreshControl code needed other than the CKRefreshControl source itself. When CKRefreshControl was first released you had to replace all calls to UIRefreshControl with calls to CKRefreshControl, and then it automatically dispatched to the correct class based on whether you were on iOS 5 or on iOS 6+.
However, with the recent contributions from John Haitas, that is no longer necessary. Instead, simply compiling and linking against the CKRefreshControl source code makes the UIRefreshControl class available when targeting iOS 5. As a result, you can simply continue to use [[UIRefreshControl alloc] init], and it will automatically work on iOS 5.
Why should you believe me? Because I'm the guy who wrote CKRefreshControl in the first place.
1) Add the 3 classes and prefix to your project:
- CKParagraphStyle.h and CKParagraphStyle.m
- CKParagraphStyle.h and CKRefreshArrowView.m
- CKRefreshControl.h and CKRefreshControl.m
- CKRefreshControl-Prefix.pch (goes into TableVCs using Refresh).
2) Add the QuartzCore.framework to the target libraries.
3) Add this method:
-(void)doRefresh:(CKRefreshControl *)sender {
NSLog(#"refreshing");
[self.refreshControl performSelector:#selector(endRefreshing) withObject:nil afterDelay:1.0];
}
Finally, use UIRefreshControl, as usual, but select the doRefresh method:
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(doRefresh:) forControlEvents:UIControlEventValueChanged];

iOS: Maximum memory in simulator?

When I start my app in the simulator it crashes immediately with "error: memory read failed"
Everything works fine on iPad/iPhone, but the when I add a simple "return;" before the core data lines, the simulator starts up fine:
return;
CCAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
IMPORTANT!!:
It does not run that code at any time, just compiles it. And if I add the "return;" before the same core data connection in another file instead, it runs fine to. Looks like there is some kind of maximum "connection" to core data or something?
I have tried Cleaning Xcode (Normal and clean build folder), cleaning the simulator (Reset content and setting), but with no success.
Additional question: Is there someway I can re-install IOS simulator?
"error: memory read failed". I received same message this morning. And I found it id related to Block.
As we know, if a class has a Block as its member, it ought to be look like this:
#property(nonatomic, copy)BlockType block;
And my mistake was forgot to use copy when add a block to a NSArray instance:
[array addObject:aBlock];
Finally I solved it by this:
MyBlockType copy = [aBlock copy];
[array addObject:copy];
[copy release];
Good luck!
Upate Mar/20/1013
Another situation causes "error: memory read failed".
- (void)blockCalledMethod{
for (BlockType b in _dictionary) {
b(self);
}
}
The key to solve my problem is to iterate NSDictionary by using .allKeys.
But the object in dictionary is Block, so it must be relative with Block.
I have got the same issue with my iPhone simulator. I have clean code in XCode
and i have reset simulator
Hope it will help

XCode analyzer not working

I am currently doing the CS193P lessons via iTunesU and the teacher mentioned the Build and Analyze option several times. He said that it was a nice tool and fun to play with.
So I tried, and noticed that it doesn't work, or that I don't understand how it should work (I think the last option).
I have a few memory leaks, and it is not warning me at all! I saw online that a blue thing should appear telling me it is a leak, but I don't see anything although I'm doing NSDictionary *dict = [[NSDictionary alloc] init];.
How is it supposed to work? From what I read on the internet I thought it should signal potential leaks. What am I doing wrong?
I'm using XCode 3.2.5.
Thanks.
Update:
This is a kind of bug, I think.
When I declare this in the interface like NSDictionary *dict; and initialize it (but nowhere deallocating it) it says nothing.
When I declare and initialize it in - (void) init and don't release it in there like:
- (void) init {
if(self = [super init])
NSDictionary *dict = [[NSDictionary alloc] init];
return self;
}
It does signal a leak. Why? Is this because of my settings? Is this a bug? If it is a bug, where and how should I report it?
It's giving you a warning because you're not deallocating it.
-(void)dealloc{
[super dealloc];
[dict dealloc];
}
It's not warning you because you should be able to release the objects as soon as you create them, and the analyzer goal is to alert you on possible leaks in your code.
You can either use autorelease, or you dealloc the object you create manually.
P.S., little curiosity: why are you using Xcode 3.2.5?
Don't know exactly if that version can, but in the latest versions of Xcode, when you run that tool, you are able to see WHAT object you are deallocating with the means of some arrows with explanation, something like
I just found out that a reboot and restart of Xcode will bring it back.

Why is app crashing in iPhone simulator; how can I fix this?

I'm working on an app that uses a navigation controller. When I build, I get no errors or warnings. I've defined a method myMethod in FirstViewController.m file, then in viewDidLoad I call the method with [self myMethod];.
When I built and ran from the Console, I got nothing. So I put NSLog() statements like so:
-(void) viewDidLoad {
NSLog(#"Entering viewDidLoad");
[self myMethod];
NSLog(#"Called myMethod");
[super viewDidLoad];
}
The Console never returns the second NSLog statement, leading me to believe that the app crashes while calling the method.
I've tried this with the simulator set to iOS 4.0.1 as well as iOS 4.1. I'm building against the iOS 4.1 SDK. I really appreciate any help you can offer.
Update: I ran the Debugger, which seems to show the problem being in myMethod. I only make it through a few lines of code in that method before I receive "EXC_BAD_ACCESS". The lines of code are:
-(void)myMethod {
NSMutableArray *someStuff;
NSMutableArray *someMoreStuff;
stuffSections=[[NSMutableArray alloc] initWithObjects:#"Some Stuff",#"Some More Stuff",nil];
someStuff=[[NSMutableArray alloc] init];
someMoreStuff=[[NSMutableArray alloc] init];
[someStuff addObject:[[NSMutableDictionary alloc]initWithObjectsAndKeys:#"Item Name",#"name",#"Item Picture.png",#"picture",#"http://theurl.net/",#"url",#"1",#"itemCode",nil]];
But it appears that I can't get past this first attempt to add something to the someStuff array.
Looks like there is a problem in "myMethod". If I had to guess, I would say you are trying to reference an object that was auto-released and not retained.
You're missing the alloc when initializing someStuff and someMoreStuff. It should be
someStuff = [[NSMutableArray alloc] init];
someMoreStuff = [[NSMutableArray alloc] init];
Have you cross checked the two MutableArrays? Do they have been allocated successfully? You get "EXC_BAD_ACCESS" when the app got into a corrupted state that is usually due to a memory management issue. I guess the arrays are not allocated.
Try allocating this way.
NSMutableArray * someStuff = [[NSMutableArray alloc]initWithCapacity:3];
NSMutableArray * someMoreStuff = [[NSMutableArray alloc]initWithCapacity:3];
add a breakpoint there are check in the debug area and confirm whether they are being allocated successfully. If there is a memory to each of these array, then they are allocated.

Resources