How to add events by JSON in MBCalendarKit - ios

I used a storyboard and ios 9 , Xcode 7.2, in this project used a calendar view and event show by web server fetch data.
I added calendar kit framework and also two file add my project first is CKDemoViewController.h and second is CKDemoViewController.m, This time create a static events. but i want to create a dynamic events. so how it possible. I tried to many times but could not create dynamic events. How it possible, please help, Thank You.
CKDemoViewController.m
#import "CKDemoViewController.h"
#import "NSCalendarCategories.h"
#import "NSDate+Components.h"
#interface CKDemoViewController () <CKCalendarViewDelegate, CKCalendarViewDataSource>
{
NSArray*date;
NSArray*title;
NSArray*img;
NSArray*des;
NSArray*evnt_ary;
NSArray*timeary;
}
#property (nonatomic, strong) NSMutableDictionary *data;
#end
#implementation CKDemoViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLRequest *req=[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:#"http://edutimeapp.com/toshow/chamber-of-commerc/ws/fetch_event.php"]];
response =[[NSMutableData alloc]init];
[NSURLConnection connectionWithRequest:req delegate:self];
self.data = [[NSMutableDictionary alloc] init];
[self setDataSource:self];
[self setDelegate:self];
// An event for the new MBCalendarKit release.
NSString *title = NSLocalizedString(#"Release MBCalendarKit 2.2.4", #"");
NSDate *date = [NSDate dateWithDay: 12 month:11 year:2016];
CKCalendarEvent *releaseUpdatedCalendarKit = [CKCalendarEvent eventWithTitle:title andDate:date andInfo:nil];
// An event for the new Hunger Games movie.
NSString *title2 = NSLocalizedString(#"The Hunger Games: Mockingjay, Part 1", #"");
NSDate *date2 = [NSDate dateWithDay:21 month:11 year:2014];
CKCalendarEvent *mockingJay = [CKCalendarEvent eventWithTitle:title2 andDate:date2 andInfo:nil];
// Integrate MBCalendarKit
NSString *integrationTitle = NSLocalizedString(#"Integrate MBCalendarKit", #"");
NSDate *integrationDate = date2;
CKCalendarEvent *integrationEvent = [CKCalendarEvent eventWithTitle:integrationTitle andDate:integrationDate andInfo:nil];
// An event for the new MBCalendarKit release.
NSString *title3 = NSLocalizedString(#"Fix bug where events don't show up immediately.", #"");
NSDate *date3 = [NSDate dateWithDay:29 month:11 year:2014];
CKCalendarEvent *fixBug = [CKCalendarEvent eventWithTitle:title3 andDate:date3 andInfo:nil];
self.data[date] = #[releaseUpdatedCalendarKit];
self.data[date2] = #[mockingJay, integrationEvent];
self.data[date3] = #[fixBug];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[response appendData:data];
NSLog(#"error receving data %#",response);
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSLog(#"Error in receiving data %#",error);
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
NSLog(#"response data %#",json);
NSArray *results = [json objectForKey:#"status"];
title = [[results valueForKey:#"event"]valueForKey:#"event_title"];
NSLog(#"event name fetch %#",title);
date =[[results valueForKey:#"event"]valueForKey:#"event_date"];
NSLog(#"event fetch %#",date);
img =[[results valueForKey:#"event"]valueForKey:#"img"];
des =[[results valueForKey:#"event"]valueForKey:#"event_detail"];
evnt_ary =[[results valueForKey:#"event"]valueForKey:#"event_name"];
timeary =[[results valueForKey:#"event"]valueForKey:#"event_time"];
}
#pragma mark - CKCalendarViewDataSource
- (NSArray *)calendarView:(CKCalendarView *)calendarView eventsForDate:(NSDate *)date
{
return [self data][date];
}
#pragma mark - CKCalendarViewDelegate
// Called before/after the selected date changes
- (void)calendarView:(CKCalendarView *)CalendarView willSelectDate:(NSDate *)date
{
}
- (void)calendarView:(CKCalendarView *)CalendarView didSelectDate:(NSDate *)date
{
}
// A row is selected in the events table. (Use to push a detail view or whatever.)
- (void)calendarView:(CKCalendarView *)CalendarView didSelectEvent:(CKCalendarEvent *)event
{
}
#end

Refer this link for code only one event set another your logic:
https://www.dropbox.com/home?preview=proj.zip
I am also solve this question in MBCalendar kit framework how to add in my project

Related

duplicate data on refresh ios

I've got my reload function reloading data properly, but I'm getting duplicate data. I've tried nil-ing out the changelist in the below spots and had no luck. Should I be nil-ing out the jsonObject? Or am I just putting it in the wrong spot.
Thanks for any help.
- (void)viewDidLoad
{
[super viewDidLoad];
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Pull to refresh"];
[refresh addTarget:self action:#selector(refreshmytable:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refresh;
NSURLSessionConfiguration *config =
[NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:config
delegate:self
// delegate:nil
delegateQueue:nil];
[self fetchFeed];
}
- (void)refreshmytable:(UIRefreshControl *)refreshControl{
[self fetchFeed]; //Added 12:12 9.16.14
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Updating"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *updated = [NSString stringWithFormat:#" Last Update: %#", [formatter stringFromDate:[NSDate date]]];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:updated];
[refreshControl endRefreshing];
[self.tableView reloadData]; //Added this 11:32 9.16.14
}
- (void)fetchFeed
{
NSString *userEID = MAP_getUsername();
//NSLog(userEID);
NSString *requestString1 = [#"URL" stringByAppendingString:userEID];
NSString *requestString2 = #"&status=pending";
NSString *requestString = [requestString1 stringByAppendingString:requestString2];
//NSLog(requestString);
/*NSString *requestString = #"http://URL";
*/
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:req
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
self.changeList = jsonObject[#"List"];
//self.changeList=nil; //tried to add here to remove duplicate data
NSLog(#"%#", self.changeList);
//- add code here to populate BNRItemStore with the change order list.
// - following code should be rewritten in fetchFeed that will load BNRItemStore.
if (self.changeList.count>0) {
for (int i = 0; i < self.changeList.count; i++) {
NSDictionary *coItem = self.changeList[i];
[[BNRItemStore sharedStore]
addItemWithApproverEid:coItem[#"approverEid"]
assignmentGroup:coItem[#"assignmentGroup"]
changeOrder:coItem[#"changeOrder"]
subcategory:coItem[#"subCatagory"]
title:coItem[#"title"]
];
}
}
//NSLog(#"sizeof(NSInteger) = %#", #(sizeof(NSInteger)));
//- end comment
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
//self.changeList=nil; //trying to null out list for refresh non duplicate data
// NSString *json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// NSLog(#"%#", json);
}];
[dataTask resume];
}
Added BNRITEM.h class
#class BNRItem;
#interface BNRItemStore : NSObject
#property (nonatomic, readonly) NSArray *allItems;
// Notice that this is a class method and prefixed with a + instead of a -
+ (instancetype)sharedStore;
- (BNRItem *)addItemWithApproverEid:(NSString *)aEid
assignmentGroup:(NSString *)aGroup
changeOrder:(NSString *)changeOrder
subcategory:(NSString *)subcategory
title:(NSString *)title;
#end
added BNRitem.m class
interface BNRItemStore ()
#property (nonatomic) NSMutableArray *privateItems;
#end
#implementation BNRItemStore
+ (instancetype)sharedStore
{
static BNRItemStore *sharedStore;
// Do I need to create a sharedStore?
if (!sharedStore) {
sharedStore = [[self alloc] initPrivate];
}
return sharedStore;
}
I believe the issue is in this code:
[[BNRItemStore sharedStore]
addItemWithApproverEid:coItem[#"approverEid"]
assignmentGroup:coItem[#"assignmentGroup"]
changeOrder:coItem[#"changeOrder"]
subcategory:coItem[#"subCatagory"]
title:coItem[#"title"]
You keep adding data to BNRItemStore but you don't remove the old one, there in nothing to do with self.changeList.
You need some way to remove all data before you add the new one, so on the beginning of the method fetchFeed you can call something like this:
[[BNRItemStore sharedStore] removeAllData];
Note I don't know that class BNRItemStore so removeAllData method probably doesn't exists, maybe there is another method to delete all data or maybe you nnd to implement one.
// Extended
I cannot see all of the method in .m file so I don't know where the data are stored by I believe it's stored in privateItems variable, maybe there is some method to remove all object from that array but it's not declared as public.
You can add a method definitions after
+ (instancetype)sharedStore;
in BNRITEM.h:
-(void)removeAllData;
And in BNRITEM.h implement it like that:
-(void)removeAllData {
[self.privateItems removeAllObjects];
}
And as I said before call [[BNRItemStore sharedStore] removeAllData]; at the beginning of fetchFeed method.

Populating my tableview with parsed json in a string

Very new to iOS, a bit lost on what to do. I actually HAVE all that I need, I just need help putting said information into my tableview now. I am debugging and everything is correct when I hover over the variables in my "init" function, but when I go down to the function that handles the cells something is just not clicking. Very frustrating having the information you need but don't know how to put it where you want.
I hate coming to SO for these kind of questions but I have exhausted all other options. Before posting on here, I have tried everything. I tried to google other projects that I can reference, did not find any that was iOS 7 or relevant to my project. I apologize for this elementary question, and thank you in advance.
MasterViewController.m
#interface MasterViewController () {
__block NSString * jsonString;
}
#end
#implementation MasterViewController
#synthesize coursesController = _coursesController;
-(void)getJSONString
{
jsonString = [JSONHelper JSONgetString:#"http://iam.colum.edu/portfolio/api/course?json=True"];
}
-(void)initCourses
{
[_coursesController.masterCoursesList
removeLastObject];
NSError *coursesError = nil;
NSArray *coursesNameList =
[NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error: &
coursesError];
if(coursesError)
NSLog(#"[%# %#] JSON error: %#", NSStringFromClass([self class]),
NSStringFromSelector(_cmd), coursesError.localizedDescription);
NSArray *coursesNames = [coursesNameList objectAtIndex:0];
for (NSString *courseName in coursesNameList) {
NSString *stringToUse = [courseName substringFromIndex:8];
//initialize variables
NSString *name = courseName;
NSInteger *courseid = 00;
NSString *imageUrl = nil;
//add current building to list
[_coursesController masterCoursesListWithName:name AndcourseID:courseid AndimageURL:imageUrl];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CoursesCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Courses *courseAtIndex = [self.coursesController objectInListAtIndex:indexPath.row];
[[cell textLabel] setText:courseAtIndex.courseName];
return cell;
}
CoursesDataController.m
#interface CoursesDataController()
-(void)initializeDefaultDataList;
#end
#implementation CoursesDataController
#synthesize masterCoursesList = _masterCoursesList;
-(void)initializeDefaultDataList
{
NSMutableArray *coursesList = [[NSMutableArray alloc] init];
Courses *course = [[Courses
alloc]initWithName:#"Loading Now..." AndcourseID:00];
[coursesList addObject:course];
}
-(void)setMasterCoursesList:(NSMutableArray *)newCourseList
{
if(_masterCoursesList != newCourseList)
{
_masterCoursesList = [newCourseList mutableCopy];
}
} //this function is created when you create a NSMutableArray MasterCoursesList
-(id)init
{
if (self = [super init])
{
[self initializeDefaultDataList];
return self;
}
return nil;
}
-(NSUInteger) countOfList
{
return [self.masterCoursesList count];
}
-(Courses *)objectInListAtIndex:(NSInteger)theIndex
{
return [self.masterCoursesList objectAtIndex:theIndex];
}
-(void)masterCoursesListWithName:(NSString *)cName
AndcourseID:(NSInteger *)cID
AndimageURL:(NSString *)cURL
{
Courses *courses;
courses = [[Courses alloc] initWithName:cName
AndcourseID:cID
AndimageURL:cURL];
[self.masterCoursesList addObject:courses];
}
-(void)courseName:(NSString *)cName
AndcourseID:(NSInteger *)cID
{
Courses *courses;
courses = [[Courses alloc] initWithName:cName AndcourseID:cID];
[self.masterCoursesList addObject:courses];
}
#end
CoursesDataController.h
#import <Foundation/Foundation.h>
#class Courses;
#interface CoursesDataController : NSObject
#property(nonatomic, copy) NSMutableArray *
masterCoursesList;
-(NSUInteger) countOfList;
-(Courses *)objectInListAtIndex:(NSInteger)theIndex;
- (void)masterCoursesListWithName:(NSString *)cName
AndcourseID:(NSInteger *)cID
AndimageURL:(NSString *)cURL;
- (void)courseName:(NSString *)cName
AndcourseID:(NSInteger *)cID;
#end
JSONHelper.m
+(NSString *)JSONgetString:(NSString *)query
{
NSString* searchURL = [NSString stringWithFormat:query];
NSError* error = nil; //error for NSUSRLConnection
NSURLResponse* response = nil;
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];
NSURL* URL = [NSURL URLWithString:searchURL];
[request setURL:URL];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setTimeoutInterval:30];
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error)
{
NSLog(#"Error performing request %#", searchURL);
return 0;
}
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"jsonString:%#", jsonString);
return jsonString;
}
I have a lot of code posted, however there are only a few lines that really matter for my question. When I hover over "name" in the following line of code [_coursesController masterCoursesListWithName:name AndcourseID:courseid AndimageURL:imageUrl];
I get what I need (it loops through each JSON array and displays each one). But in the function that handles my cells, when I hover over courseName it doesn't say anything.
Courses *courseAtIndex = [self.coursesController objectInListAtIndex:indexPath.row];
[[cell textLabel] setText:courseAtIndex.courseName];
EDITS:
numberOfRowsInSection function in MasterViewController.m
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.coursesController countOfList];
}
Try this,
in CoursesDataController.m
-(void)initializeDefaultDataList
{
self.masterCoursesList = [[NSMutableArray alloc] init];
Courses *course = [[Courses
alloc]initWithName:#"Loading Now..." AndcourseID:00];
[self.masterCoursesList addObject:course];
}

Singleton UIManagedDocument is not writing transaction logs to cloud

I have an app that uses a single UIManagedDocument as the data store which I access through a singleton using the method in Justin Driscoll's blog.
This works fine, but when I set my ubiquity keys for the persistentStoreOptions and change state notifications, the app only runs in the sandbox and there is no network activity.
Here is the execution flow ...
1. App opens to a landing screen where the singleton is created.
2. Once the UIManagedDocument is open I check for cloud permissions and if all is good to go and we have a ubiquity container, I overwrite the persistentStoreOptions with the cloud contentNameKey and contentUrlKey options.
Here is the code …
// DataStore.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
typedef void (^OnDocumentReady) (UIManagedDocument *appDataStore);
#interface DataStore : NSObject
#property (strong, nonatomic) UIManagedDocument *appDataStore;
+ (DataStore *)sharedDocumentHandler;
- (void)performWithDocument:(OnDocumentReady)onDocumentReady;
#end
// DataStore.m
#import "DataStore.h"
#import "HashDefines.h"
#interface DataStore ()
#property (nonatomic)BOOL preparingDocument;
#property (nonatomic, strong) NSFileCoordinator *coordinator;
#property (strong, nonatomic) NSString *localDocumentsPath;
#property (strong, nonatomic) NSURL *localDocumentsURL;
#property (strong, nonatomic) NSURL *localFileURL;
#end;
#implementation DataStore
#synthesize appDataStore = _appDataStore;
#synthesize localDocumentsPath = _localDocumentsPath;
#synthesize localDocumentsURL = _localDocumentsURL;
#synthesize localFileURL = _localFileURL;
static DataStore *_sharedInstance;
#synthesize coordinator = _coordinator;
#define LOCAL_DATA_STORE_FILE_NAME #“QR App DataStore"
#pragma mark - synthesiser overiders
+ (DataStore *)sharedDocumentHandler
{
static dispatch_once_t once;
dispatch_once(&once, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
#pragma mark - Key Paths
#pragma mark Local Documents
- (NSString *) localDocumentsPath
{
if (!_localDocumentsPath) {
_localDocumentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
}
return _localDocumentsPath;
}
- (NSURL *) localDocumentsURL
{
if (!_localDocumentsURL) {
_localDocumentsURL = [NSURL fileURLWithPath:self.localDocumentsPath];
}
return _localDocumentsURL;
}
#pragma mark - File URLs
- (NSURL *) localFileURL: (NSString *) filename
{
if (!filename) return nil;
NSURL *fileURL = [[self localDocumentsURL] URLByAppendingPathComponent:filename];
return fileURL;
}
#pragma mark - the juicy bits
#pragma mark - initialisers
- (id)init
{
self = [super init];
if (self) {
NSLog(#"appDataStore does NOT exist ... building one now");
[self initCoreDataInTheSandbox];
}
return self;
}
- (void)initCoreDataInTheSandbox
{
NSURL *localURL = [self localFileURL:LOCAL_DATA_STORE_FILE_NAME];
self.appDataStore = [[UIManagedDocument alloc] initWithFileURL:localURL];
// Set our document up for automatic migrations
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
self.appDataStore.persistentStoreOptions = options;
NSLog(#"1. DS persistentStoreOptions: %#", self.appDataStore.persistentStoreOptions);
}
- (void)performWithDocument:(OnDocumentReady)onDocumentReady
{
NSLog(#"1. DS Begin performWithDocument: %#", self.appDataStore);
void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success) {
onDocumentReady(self.appDataStore);
NSLog(#"2. DS into the block ... onDocumentReady:");
self.preparingDocument = NO; // release in completion handler
};
if(!self.preparingDocument) {
NSLog(#"3. DS preparing document: dataStore.appDataStore: %#", self.appDataStore);
// "lock", so no one else enter here
self.preparingDocument = YES;
if(![[NSFileManager defaultManager] fileExistsAtPath:[self.appDataStore.fileURL path]]) {
NSLog(#"4. DS creating document: dataStore.appDataStore: %#", self.appDataStore);
[self.appDataStore saveToURL:self.appDataStore.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:OnDocumentDidLoad];
[self.appDataStore openWithCompletionHandler:OnDocumentDidLoad];
} else if (self.appDataStore.documentState == UIDocumentStateClosed) {
NSLog(#"5. DS dataStore.appDataStore.documentState: %d ... closed", self.appDataStore.documentState);
[self.appDataStore openWithCompletionHandler:OnDocumentDidLoad];
} else if (self.appDataStore.documentState == UIDocumentStateSavingError) {
NSLog(#"6. DS dataStore.appDataStore.documentState: %d ... saving error", self.appDataStore.documentState);
[self.appDataStore openWithCompletionHandler:OnDocumentDidLoad];
} else if (self.appDataStore.documentState == UIDocumentStateNormal) {
NSLog(#"7. DS dataStore.appDataStore.documentState: %d ... open", self.appDataStore.documentState);
OnDocumentDidLoad(YES);
}
} else {
// try until document is ready (opened or created by some other call)
NSLog(#"8. DS preparing document - NOT ... trying again");
[self performSelector:#selector(performWithDocument:) withObject:onDocumentReady afterDelay:0.5];
}
NSLog(#"9. DS Exiting performWithDocument: %#", self.appDataStore);
}
#end
// CloudConnector.h
#import "DataStore.h"
#interface CloudConnector : NSObject
- (void)hookUpCloudForDocument:(UIManagedDocument *)document;
(NSManagedObjectContext*)managedObjectContext;
- (NSString *) documentState: (int) state;
#end
#define ICLOUD_TOKEN_KEY #“com.apple.QR-App.UbiquityIdentityToken"
#define CLOUD_IS_UBIQUITOUS #"sweet ubiquity"
#define LOCAL_DATA_STORE_FILE_NAME #“QR App DataStore"
#define CLOUD_DATA_STORE_FILE_NAME #"com~app~QR-App~cloudstore"
//CloudConnector.m
#import "CloudConnector.h"
#import "HashDefines.h"
#interface CloudConnector ()
#property (strong, nonatomic) NSString *localDocumentsPath;
#property (strong, nonatomic) NSURL *localDocumentsURL;
#property (strong, nonatomic) NSURL *localFileURL;
#property (strong, nonatomic) NSURL *ubiquityDataFileURL;
#property (nonatomic)BOOL preparingDocument;
#property (nonatomic, strong) NSFileCoordinator *coordinator;
- (NSURL *) localFileURL: (NSString *) filename;
- (NSURL *) ubiquityDataFileURL: (NSString *) filename;
- (BOOL) isLocal: (NSString *) filename;
- (NSString *) documentState: (int) state;
#end;
#implementation CloudConnector
#synthesize coordinator = _coordinator;
#synthesize localDocumentsPath = _localDocumentsPath;
#synthesize localDocumentsURL = _localDocumentsURL;
#synthesize localFileURL = _localFileURL;
#synthesize ubiquityDataFileURL = _ubiquityDataFileURL;
#pragma mark - synthesiser overiders
#pragma mark - the juicy bits
- (void)checkUbiquityStatus
{
id currentiCloudToken = [[NSFileManager defaultManager] ubiquityIdentityToken];
if (currentiCloudToken) {
NSData *newTokenData =
[NSKeyedArchiver archivedDataWithRootObject: currentiCloudToken];
[[NSUserDefaults standardUserDefaults]
setObject: newTokenData
forKey: ICLOUD_TOKEN_KEY];
} else {
[[NSUserDefaults standardUserDefaults]
removeObjectForKey: ICLOUD_TOKEN_KEY];
}
}
#pragma mark - Key Paths
#pragma mark Local Documents
- (NSString *) localDocumentsPath
{
if (!_localDocumentsPath) {
_localDocumentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
}
return _localDocumentsPath;
}
- (NSURL *) localDocumentsURL
{
if (!_localDocumentsURL) {
_localDocumentsURL = [NSURL fileURLWithPath:self.localDocumentsPath];
}
return _localDocumentsURL;
}
#pragma mark - File URLs
- (NSURL *) localFileURL: (NSString *) filename
{
if (!filename) return nil;
NSURL *fileURL = [[self localDocumentsURL] URLByAppendingPathComponent:filename];
return fileURL;
}
- (NSURL *) ubiquityDataFileURL: (NSString *) filename forContainer: (NSString *) container
{
if (!filename) return nil;
NSURL *fileURL = [[self ubiquityDataURLForContainer:container] URLByAppendingPathComponent:filename];
return fileURL;
}
- (NSURL *) ubiquityDataFileURL: (NSString *) filename
{
return [self ubiquityDataFileURL:filename forContainer:nil];
}
#pragma mark Ubiquity Data
- (NSURL *) ubiquityDataURLForContainer: (NSString *) container
{
return [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:container];
}
- (NSArray *) contentsOfUbiquityDataFolderForContainer: (NSString *) container
{
NSURL *targetURL = [self ubiquityDataURLForContainer:container];
if (!targetURL) return nil;
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:targetURL.path error:nil];
return array;
}
- (BOOL) isLocal: (NSString *) filename
{
if (!filename) return NO;
NSURL *targetURL = [self localFileURL:filename];
if (!targetURL) return NO;
return [[NSFileManager defaultManager] fileExistsAtPath:targetURL.path];
}
- (NSString *) documentState: (int) state
{
if (!state) return #"Document state is normal";
NSMutableString *string = [NSMutableString string];
if ((state & UIDocumentStateClosed) != 0)
[string appendString:#"Document is closed\n"];
if ((state & UIDocumentStateInConflict) != 0)
[string appendString:#"Document is in conflict"];
if ((state & UIDocumentStateSavingError) != 0)
[string appendString:#"Document is experiencing saving error"];
if ((state & UIDocumentStateEditingDisabled) != 0)
[string appendString:#"Document editing is disbled" ];
return string;
}
#pragma mark - initialisers
- (void)hookUpCloudForDocument:(UIManagedDocument *)document
{
// checking for ubiquity
NSLog(#"checking for ubiquity");
[self checkUbiquityStatus];
// THE FOLLOWING CODE DOESN'T WORK
if ([[NSUserDefaults standardUserDefaults] objectForKey:ICLOUD_TOKEN_KEY]) {
// cloud permissions are good to go.
NSLog(#"cloud permissions are good to go.");
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
NSURL *url = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier: nil];
NSLog(#"bikky url: %#", url);
if (url) { // != nil) {
// Your app can write to the ubiquity container
dispatch_async (dispatch_get_main_queue (), ^(void) {
// On the main thread, update UI and state as appropriate
[self setupCoreDataInTheCloudForDocument:document];
});
}
});
}
}
- (void) setupCoreDataInTheCloudForDocument:(UIManagedDocument *)document
{
NSLog(#"1. cc.setupCoreDataInTheCloudForDocument: %#", document);
NSURL *localURL = [self localFileURL:LOCAL_DATA_STORE_FILE_NAME];
NSURL *cloudURL = [self ubiquityDataFileURL:CLOUD_DATA_STORE_FILE_NAME];
// Set the persistent store options to point to the cloud
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
// [document.fileURL lastPathComponent], NSPersistentStoreUbiquitousContentNameKey,
localURL, NSPersistentStoreUbiquitousContentNameKey,
cloudURL, NSPersistentStoreUbiquitousContentURLKey,
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
document.persistentStoreOptions = options;
NSLog(#"2. cc.document.persistentStoreOptions: %#", document.persistentStoreOptions);
// Register as presenter
self.coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:document];
[NSFileCoordinator addFilePresenter:document];
// // THIS CODE IS INLINE FROM iOS 5 COOK BOOK
// // I EXECUTE THIS IN (void)performWithDocument:(OnDocumentReady)onDocumentReady
//
// // Check at the local sandbox
// if ([self isLocal:LOCAL_DATA_STORE_FILE_NAME])
// {
// NSLog(#"Attempting to open existing file");
// [document openWithCompletionHandler:^(BOOL success){
// if (!success) {NSLog(#"Error opening file"); return;}
// NSLog(#"File opened");
// }];
// }
// else
// {
// NSLog(#"Creating file.");
// // 1. save it out, 2. close it, 3. read it back in.
// [document saveToURL:localURL
// forSaveOperation:UIDocumentSaveForCreating
// completionHandler:^(BOOL success){
// if (!success) { NSLog(#"7. Error creating file"); return; }
// NSLog(#"File created");
// [document closeWithCompletionHandler:^(BOOL success){
// NSLog(#"Closed new file: %#", success ? #"Success" : #"Failure");
//
// [document openWithCompletionHandler:^(BOOL success){
// if (!success) {NSLog(#"Error opening file for reading."); return;}
// NSLog(#"File opened for reading.");
// }];
// }];
// }];
// }
//}
#end
I call the singleton as follows …
- (void)viewDidLoad
{
[super viewDidLoad];
if (!self.codeGeneratorDataStore) {
NSLog(#"MVC.viewDidLoad: Grab local instance of document from data store singleton");
[[DataStore sharedDocumentHandler] performWithDocument:^(UIManagedDocument *document) {
self.codeGeneratorDataStore = document;
// Do stuff with the document, set up a fetched results controller, whatever.
// NSLog(#"IN: _codeGeneratorDataStore.documentState : %u", _codeGeneratorDataStore.documentState);
if (![self.codeGeneratorDataStore.persistentStoreOptions objectForKey:NSPersistentStoreUbiquitousContentNameKey]) {
NSLog(#"MVC.viewDidLoad: We have a document, hooking up cloud now ... \n%#", document);
[self.cloudConnector hookUpCloudForDocument:self.codeGeneratorDataStore];
}
[self setupFetchedResultsController];
}];
NSLog(#"GVC.viewDidLoad: Subscribing to notifications");
[self subscribeToCloudNotifications];
}
[self checkDocumentStatus];
}
Then I check the document status …
- (void)checkDocumentStatus {
NSLog(#"MVC.checkDocumentStatus\n Document: %#\n persistentStoreOptions: %#", self.codeGeneratorDataStore, self.codeGeneratorDataStore.persistentStoreOptions);
if (![[
NSFileManager defaultManager] fileExistsAtPath:[self.codeGeneratorDataStore.fileURL path]]) {
[self.codeGeneratorDataStore saveToURL:self.codeGeneratorDataStore.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog(#"1. MVC self.codeGeneratorDataStore.documentState: %#", [NSString stringWithFormat:#"%u", self.codeGeneratorDataStore.documentState]);
}];
} else if (self.codeGeneratorDataStore.documentState == UIDocumentStateClosed) {
[self.codeGeneratorDataStore openWithCompletionHandler:^(BOOL succes) {
NSLog(#"2. MVC self.codeGeneratorDataStore.documentState: %#", [NSString stringWithFormat:#"%u", self.codeGeneratorDataStore.documentState]);
}];
} else if (self.codeGeneratorDataStore.documentState == UIDocumentStateNormal) {
NSLog(#"3. MVC self.codeGeneratorDataStore.documentState: %#", [NSString stringWithFormat:#"%u", self.codeGeneratorDataStore.documentState]);
}
}
Setup and register for notifications ...
- (void)subscribeToCloudNotifications
{
// subscribe to the NSPersistentStoreDidImportUbiquitousContentChangesNotification notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(documentStateChanged:)
name:UIDocumentStateChangedNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(documentContentsDidUpdate:)
name:NSPersistentStoreDidImportUbiquitousContentChangesNotification
object:nil];
NSLog(#"MVC.subscribeToCloudNotifications: notification subscriptions are good to go");
}
- (void) documentContentsDidUpdate: (NSNotification *) notification
{
NSLog(#"CMVC notification: documentContentsDidUpdate");
NSDictionary *userInfo = notification.userInfo;
[self.codeGeneratorDataStore.managedObjectContext performBlock:^{[self mergeiCloudChanges:userInfo forContext:self.codeGeneratorDataStore.managedObjectContext];}];
}
// When notified about a cloud update, start merging changes
- (void)documentStateChanged: (NSNotification *)notification
{
NSLog(#"CMVC notification: documentStateChanged");
// NSLog(#"Document state change: %#", [CloudHelper documentState:self.codeGeneratorDataStore.documentState]);
UIDocumentState documentState = self.codeGeneratorDataStore.documentState;
if (documentState & UIDocumentStateInConflict)
{
// This application uses a basic newest version wins conflict resolution strategy
NSURL *documentURL = self.codeGeneratorDataStore.fileURL;
NSArray *conflictVersions = [NSFileVersion unresolvedConflictVersionsOfItemAtURL:documentURL];
for (NSFileVersion *fileVersion in conflictVersions) {
fileVersion.resolved = YES;
}
[NSFileVersion removeOtherVersionsOfItemAtURL:documentURL error:nil];
}
}
// Merge the iCloud changes into the managed context
- (void)mergeiCloudChanges:(NSDictionary*)userInfo forContext:(NSManagedObjectContext*)managedObjectContext
{
#autoreleasepool
{
// NSLog(#"Merging changes from cloud");
NSMutableDictionary *localUserInfo = [NSMutableDictionary dictionary];
NSSet *allInvalidations = [userInfo objectForKey:NSInvalidatedAllObjectsKey];
NSString *materializeKeys[] = { NSDeletedObjectsKey, NSInsertedObjectsKey };
if (nil == allInvalidations)
{
// (1) we always materialize deletions to ensure delete propagation happens correctly, especially with
// more complex scenarios like merge conflicts and undo. Without this, future echoes may
// erroreously resurrect objects and cause dangling foreign keys
// (2) we always materialize insertions to make new entries visible to the UI
int c = (sizeof(materializeKeys) / sizeof(NSString *));
for (int i = 0; i < c; i++)
{
NSSet *set = [userInfo objectForKey:materializeKeys[i]];
if ([set count] > 0)
{
NSMutableSet *objectSet = [NSMutableSet set];
for (NSManagedObjectID *moid in set)
[objectSet addObject:[managedObjectContext objectWithID:moid]];
[localUserInfo setObject:objectSet forKey:materializeKeys[i]];
}
}
// (3) we do not materialize updates to objects we are not currently using
// (4) we do not materialize refreshes to objects we are not currently using
// (5) we do not materialize invalidations to objects we are not currently using
NSString *noMaterializeKeys[] = { NSUpdatedObjectsKey, NSRefreshedObjectsKey, NSInvalidatedObjectsKey };
c = (sizeof(noMaterializeKeys) / sizeof(NSString*));
for (int i = 0; i < 2; i++)
{
NSSet *set = [userInfo objectForKey:noMaterializeKeys[i]];
if ([set count] > 0)
{
NSMutableSet *objectSet = [NSMutableSet set];
for (NSManagedObjectID *moid in set)
{
NSManagedObject *realObj = [managedObjectContext objectRegisteredForID:moid];
if (realObj)
[objectSet addObject:realObj];
}
[localUserInfo setObject:objectSet forKey:noMaterializeKeys[i]];
}
}
NSNotification *fakeSave = [NSNotification notificationWithName:NSManagedObjectContextDidSaveNotification object:self userInfo:localUserInfo];
[managedObjectContext mergeChangesFromContextDidSaveNotification:fakeSave];
}
else
[localUserInfo setObject:allInvalidations forKey:NSInvalidatedAllObjectsKey];
[managedObjectContext processPendingChanges];
// [self performSelectorOnMainThread:#selector(performFetch) withObject:nil waitUntilDone:NO];
}
}
and we’re good to go - the app runs but with no network activity. Why aren't the transaction logs being uploaded?
Any assistance would be greatly appreciated here. Its been doing my head in for a week now and i’m at my wit’s end.
I answered this question previously in email, but I'm positing my answer here as well for completeness.
Is this an iOS 7-only app, or does it need to support iOS 5 or 6 as well?
I would not recommend mixing iCloud and Core Data in anything that still has to support iOS 5 and 6. However, the new support for iOS 7 seems pretty solid. I haven’t deployed a multi-million user app with it—so I wouldn’t say it’s battle tested, but it seems to be a lot more robust. In my preliminary testing, it handled everything I threw at it with no problems.
Also, is the sample code that you’re following up-to-date for iOS 7? It looks like it’s following some older patterns. This could cause a lot of problems, since the way the system operates has changed considerably in iOS 7.
For example, in iOS 7, we generally only need to set the NSPersistentStoreUbiquitousContentNameKey. Unless we’re trying to support a legacy core data stack, we don’t need to set the content URL key.
Also, there is a huge difference in how the core data stack is set up under iOS 7. When we first set up an iCloud persistent store, iOS 7 will create a local copy (the fallback store) for us automatically. We can use the store—but the changes will only be stored locally. When the iCloud version is ready, it will then send a NSPersistentStoreCoordinatorStoresWillChangeNotification. We’re supposed to save any changes and then reset our managed object context.
Again, it looks like your code is manually setting up its own fallback store—which may be part of the problem.
If you’re working from old examples, I’d actually recommend throwing that code away and starting over. Watch the “What’s New in Core Data and iCloud” video from WWDC 2013. It does a great rundown on the new technologies, and the current best practices.
My guess is that you’re getting the fallback store, but it’s never switching over to the iCloud store. Look in the console log when you run the app. You should see something like the following:
-[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: p Ubiquity:
mobile~C9C8554A-BD44-43C3-AC54-603046EF0162:com~freelancemad p science~HealthBeat
Using local storage: 1
Here, “Using local storage: 1” means you’re using the fallback store. In a minute or two (or sometimes longer) you’ll see a similar message with “Using local storage: 0”. That means you’re now using the iCloud store.
Also, when you run the application, be sure to open the Debug Navigator in Xcode. It should have a profiler for iCloud, that shows you whenever data was uploaded to or downloaded from the cloud.
I hope that helps,
-Rich-

Cannot reload table view in IOS7

I am a quite new to IOS development and keep having struggle with it. I would like to display phone list which an user has from my server but tableview does not display items. I have got data from server well and I think settings for UItableView is correct. Here is my code:
STKPhoneHolderViewController.h
#import <UIKit/UIKit.h>
#import "STKSimpleHttpClientDelegate.h"
#interface STKPhoneHolderViewController : UITableViewController <UITableViewDataSource, STKSimpleHttpClientDelegate>
#property (strong, nonatomic) IBOutlet UITableView *phoneTable;
#property (strong, nonatomic) NSMutableArray *phoneArray;
#end
STKPhoneHolderViewController.m
#implementation STKPhoneHolderViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.phoneTable.dataSource = self;
self.phoneArray = [[NSMutableArray alloc]init];
[self loadPhoneList];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.phoneArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"PhoneCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
STKPhoneHolder *phoneHolder = [self.phoneArray objectAtIndex:indexPath.row];
[cell.textLabel setText:phoneHolder.userName];
return cell;
}
#pragma Custom method
- (void) loadPhoneList
{
self.phoneArray = [[NSMutableArray alloc]init];
STKSimpleHttpClient *client = [[STKSimpleHttpClient alloc]init];
client.delegate = self;
NSString *userId = #"your_id_h";
NSString *sUrl = [NSString stringWithFormat:#"%#%#?userid=%#",
MOBILE_API_URL,
PHONEHOLDER_URI,
userId];
[client send:sUrl data:#""];
}
#pragma STKSimpleHttpClientDelegate
-(void) complete:(STKHttpResult*) result
{
if (result.ok != YES){
[STKUtility alert:result.message];
return;
}
self.phoneArray = (NSMutableArray*)result.result;
for (STKPhoneHolder *holder in self.phoneArray) {
NSLog(#"%#", [holder description]);
}
[self.phoneTable reloadData];
NSLog(#" isMainThread(%d)", [NSThread isMainThread] );
}
#end
STKSimpleHttpClient.m
#import "STKSimpleHttpClient.h"
#import "STKSimpleHttpClientDelegate.h"
#implementation STKSimpleHttpClient
NSMutableData *responseData;
STKHttpResult *httpResult;
void (^completeFunction)(STKHttpResult *);
- (void) send:(NSString*)url
data:(NSString*)data
{
httpResult = [[STKHttpResult alloc]init];
dispatch_async(dispatch_get_main_queue(), ^{
if ( data == nil) return;
//Get request object and set properties
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: url]];
//set header for JSON request and response
[urlRequest setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[urlRequest setValue:#"application/json" forHTTPHeaderField:#"Accept"];
//set http method to POST
[urlRequest setHTTPMethod:#"POST"];
//set time out
[urlRequest setTimeoutInterval:20];
NSData *body = [data dataUsingEncoding:NSUTF8StringEncoding];
//set request body
urlRequest.HTTPBody = body;
//connect to server
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
if (conn==nil){
//Do something
}
});
}
#pragma mark - NSURLConnection Delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
[responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable noow
NSError *error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
BOOL ok = [[json objectForKey:#"ok"] boolValue];
NSString *message = [json objectForKey:#"message"];
if (ok == NO) {
[httpResult setError:message];
} else {
[httpResult setSuccess:[json objectForKey:#"result"]];
}
if (self.delegate !=nil) {
[self.delegate complete:httpResult];
}
responseData = nil;
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
// Check the error var
if (self.delegate !=nil) {
[self.delegate complete:[httpResult setError:#"Connection failed."]];
}
}
STKPhoneHolder.m
#import <Foundation/Foundation.h>
#interface STKPhoneHolder : NSObject
#property NSString *deviceId;
#property NSString *userId;
#property NSString *userName;
#property NSString *msn;
- (id) initWithDeviceId:(NSString*)aDeviceId
userId:(NSString*)aUserId
userName:(NSString*)aUserName
msn:(NSString*)aMsn;
#end
Log:
2013-12-17 16:14:23.447 [5323:70b] {
deviceId = 11111;
email = "";
msn = 11111111;
role = "";
userId = aaaaaa;
userName = "Joshua Pak";
}
2013-12-17 16:14:23.448 [5323:70b] {
deviceId = 22222;
email = "";
msn = 2222222;
role = "";
userId = bbbbb;
userName = "Jasdf Pak";
}
2013-12-17 16:14:23.449 Stalker[5323:70b] isMainThread(1)
I can see the log printing phoneArray with two phones in 'complete' method but tableview just display "No record". Tableview does not render again even though I called reloadData method. I made sure that [self.phoneTable reloadData] is called in debugging mode.
What do I have to do more?
Try to call reloadData in main thread
#pragma STKSimpleHttpClientDelegate
-(void) complete:(STKHttpResult*) result
{
if (result.ok != YES){
[STKUtility alert:result.message];
return;
}
self.phoneArray = (NSMutableArray*)result.result;
for (STKPhoneHolder *holder in self.phoneArray) {
NSLog(#"%#", [holder description]);
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.phoneTable reloadData];
}
}
Or you can use performSelectorOnMainThread
[self.phoneTable performSelectorOnMainThread:#selector(reloadData)
withObject:nil
waitUntilDone:NO];
I am guessing STKSimpleHttpClient class is calling complete delegate function on different thread, all user interface interaction suppose to be called from main thread.
Try this code to see which thread you are in from the complete delegate function
NSLog(#" isMainThread(%d)", [NSThread isMainThread] );
check this. does the code load the tableview before you get information from web services. if so then write the statement [tableview Reload]; next to the web services information getting process. This will help
It's not necessary to specify the number of sections, but you might want to do it with this code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
I see you're using a Table View Controller, which already has a tableView reference self.tableView.
Like #rdelmar said, you could use that reference instead of your phoneTable:
[[self tableView] setDataSource:self];
[[self tableView] setDelegate:self];
[[self tableView] reloadData];

Map Annotations from JSON -- No annotations showing up [duplicate]

I've been through several different tutorials trying to get this working, but they seem to gloss over some crucial steps that a beginner might not know.
I have a JSON file at a URL with name, latitude, and longitude listed. How can I import that to an array or dictionary (I don't know the difference), and then iterate over it and create a new annotation with each iteration.
IOS6, Storyboards
_ Added Code _
ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface ViewController : UIViewController {}
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#property (nonatomic, strong) NSMutableData *downloadData;
#end
ViewController.m
#import "ViewController.h"
#import "MapViewAnnotation.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_downloadData = [NSMutableData new];
NSURL *requestURL = [NSURL URLWithString:#"OMITTED/apptest/locations.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_downloadData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
id parsed = [NSJSONSerialization JSONObjectWithData:_downloadData options:kNilOptions error:nil];
for (NSDictionary *pointInfo in parsed)
{
NSLog([parsed objectForKey:#"name"]);
double xCoord = [(NSNumber*)[parsed objectForKey:#"lat"] doubleValue];
double yCoord = [(NSNumber*)[parsed objectForKey:#"lon"] doubleValue];
CLLocationCoordinate2D coords = CLLocationCoordinate2DMake(xCoord, yCoord);
MKPointAnnotation *point = [MKPointAnnotation new];
point.coordinate = coords;
point.title = [parsed objectForKey:#"name"];
[self.mapView addAnnotation:point]; // or whatever your map view's variable name is
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidUnload {
[super viewDidUnload];
// ARC Problem --- [_mapView release];
self.mapView = nil;
}
#end
With iOS 5 there's a JSONSerializer class that can convert the raw JSON data from your URL into an array or dictionary as appropriate.
You'll need to download the data from the server:
NSURL *requestURL = [NSURL URLWithString:#"<your url here>"];
NSURLRequest *request = [NSURLRequest requestWithURL:requestURL];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
[connection start];
Then you'll add these delegate methods:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_downloadData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
id parsed = [NSJSONSerialization JSONObjectWithData:_downloadData options:kNilOptions error:nil];
}
_downloadData is an instance variable or property of your class of type NSMutableData.
That parsed variable will contain your data from the server. It's probably an array if it's a list of points, so you can iterate through it using fast enumeration:
for (NSDictionary *pointInfo in parsed) {
double xCoord = [(NSNumber*)[parsed objectForKey:#"<key for lat coord>"] doubleValue];
double yCoord = [(NSNumber*)[parsed objectForKey:#"<key for long coord>"] doubleValue];
CLLocationCoordinate2D coords = CLLocationCoordinate2DMake(xCoord, yCoord);
MKPointAnnotation *point = [[MKPointAnnotation new] autorelease];
point.coordinate = coords;
point.title = [parsed objectForKey:#"<key for title>"];
[self.mapView addAnnotation:point]; // or whatever your map view's variable name is
}
I have an open source project on GitHub that uses the serializer with the NSCoding protocol so you can automatically create instances right from the JSON stream.
It's here.

Resources