I am trying to make an app that permits the user to make events in one specified calendar.
The problem is that:
I can't find a solution to know if there's a calendar with the title that I want to use.
If the list is empty I write a code that creates the calendar but if the list isn't empty I need to know if there's a calendar with the calendar.title that I need.
If there isn't any calendar, I create the calendar; if there is I add the event to this calendar.
Below is the code I am using:
EKEvent *myEvent;
EKEventStore *store;
EKSource* localSource;
EKCalendar* newCal;
store = [[EKEventStore alloc] init];
myEvent = [EKEvent eventWithEventStore: store];
NSString* title = [arguments objectAtIndex:1];
NSString* location = [arguments objectAtIndex:2];
NSString* message = [arguments objectAtIndex:3];
NSString* startDate = [arguments objectAtIndex:4];
NSString* endDate = [arguments objectAtIndex:5];
NSString* calendarTitle = [arguments objectAtIndex:6];
//NSString* calID = nil;
//int i = 0;
EKCalendar* calendar = nil;
if(calendarTitle == nil){
calendar = store.defaultCalendarForNewEvents;
} else {
NSIndexSet* indexes = [store.calendars indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
*stop = false;
EKCalendar* cal = (EKCalendar*)obj;
if(cal.title == calendarTitle){
*stop = true;
}
return *stop;
}];
if (indexes.count == 0) {
//if list is empty i haven't calendars then i need to create it
for (EKSource* source in store.sources)
{
if (source.sourceType == EKSourceTypeLocal)
{
localSource = source;
break;
}
}
if (!localSource) return;
newCal = [EKCalendar calendarWithEventStore:store];
calendar.source = localSource;
calendar.title = calendarTitle;
NSError* error;
bool success = [store saveCalendar:newCal commit:YES error:&error];
if (error != nil)
{
NSLog(error.description);
}
//calendar created
} else {
//!Empty List i need to search the calendar with the title = calendarTitle
//And if there isn't i need to create it
//calendar = [store.calendars objectAtIndex:[indexes firstIndex]];
}
}
I think the problem is your implementation of indexesOfObjectsPassingTest. You're not returning any indexes, and since you try to stop it after it finds one index, you should just use the singular version indexOfObjectPassingTest. You can very simply write that like this:
NSUInteger* indx = [store.calendars indexOfObjectPassingTest:^BOOL(EkCalendar *cal, NSUInteger idx, BOOL *stop) {
return [cal.title isEqualToString:calendarTitle];
}];
Then, after checking to see that index is not NSNotFound use
calendar = store.calendars[indx];
Related
I'm trying to simply search for videos using a query, which is working perfectly using the below code.
// Create a service object for executing queries
GTLServiceYouTube *service = [[GTLServiceYouTube alloc] init];
// Services which do not require sign-in may need an API key from the
// API Console
service.APIKey = #"AIzaSy...";
// Create a query
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id,snippet"];
query.maxResults = 10;
query.q = searchBar.text;
query.videoEmbeddable = #"true";
query.type = #"video";
//query.country = #"US";
// Execute the query
GTLServiceTicket *ticket = [service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
// This callback block is run when the fetch completes
if (error == nil) {
GTLYouTubeSearchListResponse *products = object;
[videoArray removeAllObjects];
// iteration of items and subscript access to items.
for (GTLYouTubeSearchResult *item in products) {
NSMutableDictionary *dictionary = [item JSONValueForKey:#"id"];
NSLog(#"%#", [dictionary objectForKey:#"videoId"]);
YoutubeVideo *video = [[YoutubeVideo alloc]init];
[video setLblTitle:item.snippet.title];
//Get youtube video image
[video setImgIconURL:[NSURL URLWithString:item.snippet.thumbnails.defaultProperty.url]];
[video setLblVideoURL:[dictionary objectForKey:#"videoId"]];
[video setLblChannelTitle:item.snippet.channelTitle];
[videoArray addObject:video];
}
reloadData = YES;
[tableView reloadData];
//Download images asynchronously
[NSThread detachNewThreadSelector:#selector(downloadImages)
toTarget:self
withObject:nil];
}else{
NSLog(#"Error: %#", error.description);
}
}];
However, now I'd like to display certain information about the video. Some of this information I can get out of
item.snippet
But I also need to get the video duration, and number of views. How can I get them using Youtube API 3.0?? I also had an idea to try using GData just for this, but it literally triples the load time to use
NSString *JSONString = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://gdata.youtube.com/feeds/api/videos/%#?v=2&alt=json", [video lblVideoURL]]] encoding:NSUTF8StringEncoding error:nil ];
How do I get the duration of the video, plus the number of views the video has?
Search query only accept ID and Snippet as parts. If you change to Video List Query you can include other parts, but you have to use one of the filters.
I think you'll have to get the video ID with the search query and do another query (Now a video query) filtering by ID (the Id you got), than you can get all other information of the videos you searched.
The problem is i'm having trouble getting the video ID, i think the API use the word "identifier" instead of "id" because it's a reserved word of objective-c.
Edit: Yeah, it was just a matter of time, just request my GTLYoutubeSearchResponse.JSON, an manipulated it as i wanted.
FIRST QUERY:
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id,snippet"];
query.maxResults = 10;
query.q = #"iphone";
query.fields = #"items(id,snippet)";
query.order = #"viewCount";
//query.channelId = #"UCsnbNwitAF9BzjjdMfRyK2g";//Kavaco
[appDelegate.service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
id object,
NSError *error) {
if (error == nil) {
appDelegate.videos = object;
[self performSegueWithIdentifier:#"videoList" sender:self];
}
else {
NSLog(#"%#", error.description);
}
}];
SECOND QUERY: In my TableViewController, inside my cellForRowAtIndexPath i do another query for each video i found. Be sure to request only the variables you need to avoid spending your credits, in my case i requested only viewCount.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell" forIndexPath:indexPath];
GTLYouTubeVideo *video = appDelegate.videos[indexPath.row];
NSMutableDictionary *videoIdJson = [video.JSON objectForKey:#"id"];
NSString *videoId = [videoIdJson objectForKey:#"videoId"];
cell.textLabel.text = video.snippet.title;
GTLQueryYouTube *query = [GTLQueryYouTube queryForVideosListWithPart:#"statistics"];
query.identifier = videoId;
query.maxResults = 1;
query.fields = #"items/statistics(viewCount)";
[appDelegate.service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
id object,
NSError *error) {
if (error == nil) {
GTLYouTubeVideoListResponse *detalhe = object;
NSMutableDictionary *responseJSON = detalhe.JSON;
NSArray *tempArray = [responseJSON objectForKey:#"items"];
NSMutableDictionary *items = tempArray[0];
NSMutableDictionary *statistics = [items objectForKey:#"statistics"];
_views = [[NSString alloc] initWithFormat:#"Views: %#",[statistics objectForKey:#"viewCount"]];
cell.detailTextLabel.text = _views;
}
else {
NSLog(#"%#", error.description);
}
}];
cell.detailTextLabel.text = _views;
return cell;
}
Hope it helps.
Collect the id from search API and do another video list API call is the proper way to do what you want to achieve. The video list API call can put multiple video ids separate by comma in the same call. The extra call shouldn't consider exhausting because this is expected behavior on API v3:
Project Member #1 je...#google.com
That's the expected behavior, and not likely to change. Since the
search.list() method can return channels, videos, and playlists, only
properties that make sense for all of those resource types are
returned in the search responses. If you need to obtain any other
properties, making a follow-up request to, e.g., videos.list() is
required. Note that you can pass in up to 50 video ids to
videos.list(), so you can effectively look up an entire page's worth
of search.list() results in a single video.list() call.
If you try https://developers.google.com/youtube/v3/docs/videos/list#try-it , you set contentDetails,statistics as the part, you should able to get the following result:
"contentDetails": {
"duration": "PT20M38S",
"dimension": "2d",
"definition": "hd",
"caption": "false",
"licensedContent": false
},
"statistics": {
"viewCount": "191",
"likeCount": "7",
"dislikeCount": "0",
"favoriteCount": "0",
"commentCount": "0"
}
PT20M38S means 20 minutes and 38 seconds, based on ISO 8601(http://en.wikipedia.org/wiki/ISO_8601)
The best way for make this is:
if (!service) {
service = [[GTLServiceYouTube alloc] init];
service.shouldFetchNextPages = YES;
service.shouldFetchInBackground = YES;
service.retryEnabled = YES;
service.APIKey = #"AIzaSyDSO2JPnM_r9VcDrDJJs_d_7Li2Ttk2AuU";
}
[youtubeList removeAllObjects];
GTLQueryYouTube *query = [GTLQueryYouTube queryForSearchListWithPart:#"id"];
query.maxResults = 50;
query.q = withText;
query.fields = #"items(id)";
query.order = #"viewCount";
query.type = #"video";
// query.videoDuration = #"long";//any-long-medium-short
__block NSInteger incrementRequest = 0;
[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error) {
NSLog(#"Error is!! = %#", error.localizedDescription);
return;
}
GTLYouTubeVideoListResponse *idsResponse = object;
for (GTLYouTubeVideoListResponse *videoInfo in object) {
[youtubeList addObject:videoInfo.JSON];
GTLQueryYouTube *query2 = [GTLQueryYouTube queryForVideosListWithIdentifier:[[videoInfo.JSON valueForKey:#"id"] valueForKey:#"videoId"] part:#"id,contentDetails,snippet,statistics"];
query2.maxResults = 1;
query2.fields = #"items(id,contentDetails,snippet,statistics)";
query2.order = #"viewCount";
[service executeQuery:query2 completionHandler:^(GTLServiceTicket *ticket, id object, NSError *error) {
if (error) {
NSLog(#"Error is!! = %#", error.localizedDescription);
return;
}
GTLYouTubeVideoListResponse *detalhe = object;
for (NSMutableDictionary *tmpDict in youtubeList) {
if ([[[tmpDict valueForKey:#"id"] valueForKey:#"videoId"] isEqualToString:[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"id"]]) {
[tmpDict removeObjectForKey:#"id"];
//condition personal
if (![Utils parseISO8601TimeIsGrater30:[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"contentDetails"] valueForKey:#"duration"]]) {
BOOL isBlockedInUs = NO;
for (NSString *countryRestric in [[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"contentDetails"] valueForKey:#"regionRestriction"] valueForKey:#"blocked"]) {
if ([countryRestric isEqualToString:#"US"]) {
isBlockedInUs = YES;
break;
}
}
if (!isBlockedInUs) {
[tmpDict addEntriesFromDictionary:detalhe.JSON];
[tmpDict setValue:[[[[detalhe.JSON valueForKey:#"items"] objectAtIndex:0] valueForKey:#"snippet"] valueForKey:#"publishedAt"] forKey:#"publishedAt"];
} else {
[youtubeList removeObject:tmpDict];
}
} else {
[youtubeList removeObject:tmpDict];
}
break;
}
}
incrementRequest ++;
if ([idsResponse.items count] == incrementRequest) {
//Finish
[self.tableView reloadData];
}
}];
}
}];
I have this method which adds events to native iphone calendar.
It is already adding monthly reminders successfully - but I want to force any monthy reminders to fall into week days (not weekends).
The NSDictionary model is simply
Id:
Start_Date__c
Finish_Date__c
Payment_Interval__c = Monthly
- (void)addRecurringEventsForPartnership:(NSDictionary *)dict{
ENTER_METHOD;
NSError *error = nil;
EKEvent *startEvent = [EKEvent eventWithEventStore:self.eventStore];
startEvent.calendar = self.defaultCalendar;
startEvent.availability = EKEventAvailabilityFree;
startEvent.startDate = [NSDate dateWithLongFormatString:[dict valueForKey:#"Start_Date__c"]];
startEvent.allDay = YES;
// startEvent.endDate = [startEvent.startDate dateByAddingTimeInterval:30*60];
startEvent.title = [dict theNameValue];
//http://stackoverflow.com/questions/7718006/xcode-why-is-my-event-not-being-added-to-the-calendar
if ([startEvent.startDate isEqualToDate:startEvent.endDate]) {
startEvent.endDate = [startEvent.startDate dateByAddingTimeInterval:30*60];;
}
// if
if ([[dict valueForKey:#"Payment_Interval__c"] isEqualToString:#"Monthly"]) {
EKRecurrenceFrequency freq = EKRecurrenceFrequencyMonthly;
int recurrenceInterval = 1;
EKRecurrenceRule *rule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:freq interval:recurrenceInterval end:nil];
startEvent.recurrenceRule = rule;
startEvent.notes = [NSString stringWithFormat:#"Id:%#",[dict valueForKey:#"Id"]];
// [self.eventStore removeEvent:startEvent span:EKSpanThisEvent error:&error];
[self.eventStore saveEvent:startEvent span:EKSpanThisEvent error:&error];
if (error != nil)
{
DLog(#"WARNING:%#",error.description);
// TODO: error handling here
}
}
// DLog(#"startEvent.endDate:%#",startEvent.endDate);
EKEvent *finishEvent = [EKEvent eventWithEventStore:self.eventStore];
finishEvent.calendar = self.defaultCalendar;
finishEvent.availability = EKEventAvailabilityFree;
finishEvent.startDate = [NSDate dateWithLongFormatString:[dict valueForKey:#"Finish_Date__c"]];
finishEvent.allDay = YES;
finishEvent.title = [NSString stringWithFormat:#"%# - Finish",[dict theNameValue]];
finishEvent.notes = [NSString stringWithFormat:#"Id:%#",[dict valueForKey:#"Id"]];
[self.eventStore saveEvent:finishEvent span:EKSpanThisEvent error:&error];
if (error != nil)
{
DLog(#"WARNING:%#",error.description);
// TODO: error handling here
}
}
Couldn't you use NSDateFormatter to get the numeric day of the week and then adjust by subtracting or adding 1 or 2 depending on which day it returned?
[dateFormatter setDateFormat:#"c"];
Will return numeric (1-7) day of the week, I believe
Here's something that works (at least in iOS7, didn't test on other systems):
EKRecurrenceRule *er = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly interval:1
daysOfTheWeek:#[[EKRecurrenceDayOfWeek dayOfWeek:2], // Monday
[EKRecurrenceDayOfWeek dayOfWeek:3], // Tuesday
[EKRecurrenceDayOfWeek dayOfWeek:4], // Wednesday
[EKRecurrenceDayOfWeek dayOfWeek:5], // Thursday
[EKRecurrenceDayOfWeek dayOfWeek:6]] // Friday
daysOfTheMonth:#[#1, #2]
monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:nil];
event.recurrenceRules = #[er];
I am retrieving google calendar events using gdata library in objective c for an iphone application, I am doing it like this,
- (void)eventsTicket:(GDataServiceTicket *)ticket finishedWithEntries:(GDataFeedCalendarEvent *)feed error:(NSError *)error
{
if( !error ){
NSMutableDictionary *dictionary;
for( int section=0; section<[data count]; section++ ){
NSMutableDictionary *nextDictionary = [data objectAtIndex:section];
GDataServiceTicket *nextTicket = [nextDictionary objectForKey:KEY_TICKET];
if( nextTicket==ticket ){ // We've found the calendar these events are meant for...
dictionary = nextDictionary;
break;
}
}
if( !dictionary )
return; // This should never happen. It means we couldn't find the ticket it relates to.
int count = [[feed entries] count]; // count for the number of events for the callendar
//099999999999999999999999999999999966666666666666669999999999999999999999999666666666666666699999999999999999999999999999999999999999999999999999999999
daily_trackAppDelegate *controller =(daily_trackAppDelegate *) [[UIApplication sharedApplication] delegate];
NSMutableArray *events = [dictionary objectForKey:KEY_EVENTS];
for( int i=0; i<count; i++ ){
[events addObject:[[feed entries] objectAtIndex:i]]; //loads the array with events
}
for( int i=0; i<count; i++ ){
NSMutableArray *temporary=[[NSMutableArray alloc]init];
[temporary removeAllObjects];
GDataEntryCalendarEvent *event = [events objectAtIndex:i];
// [controller.googlearray addObject:event];
GDataWhen *when = [[event objectsForExtensionClass:[GDataWhen class]] objectAtIndex:0];
if( when ){
NSDate *date1 = [[when startTime] date];
NSDate *date = [date1 dateByAddingTimeInterval:18000.0];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yy-MM-dd-HH-mm"];
[temporary addObject:date];///1 date
NSDate *date11=[[when endTime] date];
NSDate *date2 = [date11 dateByAddingTimeInterval:18000.0];
// [controller.array_objject.google_events insertObject:date atIndex:i];///2 date
[temporary addObject:date2];///1 date
[dateFormatter release];
}
//[controller.array_objject.google_events insertObject:[[event title] stringValue] atIndex:i]; /////3 title
[temporary addObject:[[event title] stringValue]];///1 date
GDataWhere *addr = [[event locations] objectAtIndex:0];
if( addr )
//[controller.array_objject.google_events insertObject:[addr stringValue] atIndex:i];///// 4 location
[temporary addObject:[addr stringValue]];
[controller.googlearray addObject:temporary];///// 4 location
}
NSURL *nextURL = [[feed nextLink] URL];
if( nextURL ){ // There are more events in the calendar... Fetch again. FETCHING*********************************
GDataServiceTicket *newTicket = [googleCalendarService fetchFeedWithURL:nextURL delegate:self didFinishSelector:#selector( eventsTicket:finishedWithEntries:error: )]; // Right back here...
// Update the ticket in the dictionary for the next batch.
[dictionary setObject:newTicket forKey:KEY_TICKET];
}
} else
[self handleError:error];
}
now I am retrieving the start and ending time, title, location etc. of the event here, but I also want to retrieve the description of the event, means if user enters any description while creating event, so in that case I want to retrieve that description or details of event too, I tried hard but in vain.
The description of an event is available as [[eventEntry content] stringValue]
I would like to insert events in my app, so they can be viewed in iPhone Calendar.app. But since I don't want to mix the user events with those from my app, I wanted to create a EKCalendar like "MyApp Events"
Is this possible ? How would you filter your events otherwise ?
Thanks !
It is absolutely possible to create your own calendar - the catch is that you need iOS 5:
EKEventStore* eventStore = [[EKEventStore alloc] init];
NSString* calendarName = #"My Cal";
EKCalendar* calendar;
// Get the calendar source
EKSource* localSource;
for (EKSource* source in eventStore.sources) {
if (source.sourceType == EKSourceTypeLocal)
{
localSource = source;
break;
}
}
if (!localSource)
return;
calendar = [EKCalendar calendarWithEventStore:eventStore];
calendar.source = localSource;
calendar.title = calendarName;
NSError* error;
bool success= [eventStore saveCalendar:calendar commit:YES error:&error];
if (error != nil)
{
NSLog(error.description);
// TODO: error handling here
}
Do you (or anyone else) have any progress with adding a new Calendar?
I've got the same situation. I can programmatically add events to the default calendar perfectly well, but I'd like to add them to a new calendar, so they don't interfere with the users exsisting events, and can be easily deleted/hidden by the user instead of removing all events manually.
You can't set the properties for a new EKCalendar object. It looks like you can only assign an exsiting one like defaultCalendarForNewEvents to an EKCalendar object.
However, I know it's possible to programmatically create a new calendar, because I've seen iPhone app doing this (without leaving the app).
Could it be that they use a workaround by doing some trick with an external ICS file?
Maybe it is possible to do this by "subscribing" to a local (on the iPhone/app filesystem) generated ICS file, instead of an URL. Does anyone have any experience with this?
This is how you can check out whether a calendar already exists with specific title.
If it does not exists then you can create it programatically.
Declare a Boolean Type Variable
BOOL doesExist=NO;
EKEventStore *eventStore=[[EKEventStore alloc] init];
NSArray *calanders=[eventStore calendarsForEntityType:EKEntityTypeEvent];
//Now Iterate through every calendar in the array and match its title
// with the title that you want to create
for(EKCalendar calendar in calendars)
{
if([[calendar title] isEqualToString:#"youdesiredname"])
{
doesExist=YES;
}
}
// so now check if our bool variable contains value YES it means that a calendar with same name/title already exists.if no then you can create
if(!doesExist)
{
NSString* calendarName = #"DesiredCalendarName";
EKCalendar* calendar;
EKSource* localSource;
for (EKSource* source in eventStore.sources) {
if (source.sourceType == EKSourceTypeLocal)
{
localSource = source;
break;
}
if (!localSource)
return;
calendar = [EKCalendar calendarWithEventStore:eventStore];
calendar.source = localSource;
calendar.title = calendarName;
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
calendar = [eventStore calendarWithIdentifier:self.calendarIdentifier];
event.calendar = calendar;
// Set the start date to the current date/time and the event duration to one hour
NSDate *startDate = [NSDate date];
event.startDate = startDate;
event.endDate = [startDate dateByAddingTimeInterval:3600];
//And to save the event to the event database:
NSError *error = nil;
BOOL result = [eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:&error];
if (result)
{
NSLog(#"Saved event to event store.")
}
else
{
NSLog(#"Error saving event: %#.", saveError);
}
NSError* error;
bool success= [eventStore saveCalendar:calendar commit:YES error:&error];
if (error != nil)
{
NSLog(error.description);
}
}
I am using TouchJSON to retrieve the JSON response from http://enbr.co.cc/TrailsApp/shops.php. In my app I use this code to handle a url scheme.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
if (!url) {
return NO;
}
NSString *urlString = [url absoluteString];
NSString *urlStringDecoded = [urlString stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSArray *list = [urlStringDecoded componentsSeparatedByString:#"="];
NSString *urlPrefix = [list objectAtIndex:0];
NSString *name = [list objectAtIndex:1];
if ([urlPrefix isEqualToString:#"tridetrails://opentrail?name"]) {
TrailViewController *trailViewController = [[TrailViewController alloc] initWithNibName:#"TrailViewController" bundle:[NSBundle mainBundle]];
trailViewController.trailToGoto = name;
[self.navigationController pushViewController:trailViewController animated:YES];
[trailViewController release];
}
if ([urlPrefix isEqualToString:#"tridetrails://openshop?name"]) {
ShopViewController *shopViewController = [[ShopViewController alloc] initWithNibName:#"ShopViewController" bundle:[NSBundle mainBundle]];
shopViewController.shopToGoto = name;
[self.navigationController pushViewController:shopViewController animated:YES];
[shopViewController release];
}
return YES;
}
How can I push the correct entry from my NSDictionary created from the JSON to the ShopViewController based on the NSString name? Here is my dictionary printed out by NSLog with NSLog(#"%#", myObj);. Thanks in advance.
{
shops = (
{
blurb = "Bootdoctors blurb";
image = bootdoctorslogo;
locations = "Mountain Village";
motto = "Bootdoctors shop motto";
name = Bootdoctors;
},
{
blurb = "Easy Rider blurb";
image = easyriderlogo;
locations = Telluride;
motto = "Easy Rider shop motto";
name = "Easy Rider";
},
{
blurb = "Paragon Ski & Sport blurb";
image = paragonskiandsportlogo;
locations = Telluride;
motto = "Paragon shop motto";
name = "Paragon Ski & Sport";
},
{
blurb = "Telluride Sports blurb";
image = telluridesportslogo;
locations = "Telluride and Mountain Village";
motto = "Telluride Sports shop motto";
name = "Telluride Sports";
}
);
}
You probably need to give a bit more information about what you are trying to do. For instance you don't say how you retrieve the dictionary containing the details of all the shops and how ShopViewController has access to this dictionary. But selecting one shop by name from the dictionary can be done with something like this:
NSDictionary *jsonResponse; // You don't say how the ShopViewController has access to
// the response so let's just assume a local variable here.
NSDictionary *foundShop = nil; // This will be selected shop after the search below
NSArray *shops = [jsonResponse objectForKey:#'shops'];
for (NSDictionary *shop in shops) {
if ([shop objectForKey:#'name'] isEqualToString:self.shopToGoto]) {
foundShop = shop;
break;
}
}
if (foundShop) {
// Do something with the dictionary keys and values in foundShop
}
else {
// Error condition - shop with required name is not present
// Handle error
}
You could use a NSPredicate to select the shop(s) you are looking for:
NSString* shopName = ...;
NSArray* shops = ...; // this is your JSON-produced array of NSDictionary Shop objects
NSPredicate* predicate = [NSPredicate predicateWithFormat: #"name == '%#'", shopName ];
NSArray* matchingShops = [shops filteredArrayUsingPredicate: predicate];
NSDictionary* firstMatchingShop = [matchingShops objectAtIndex: 0];