how can make Custom Delegate For Custom UIView objective c , OK button not working - objective-c

Here is my affected code:
#import "AddTeamView.h"
#import <AFNetworking.h>
#implementation AddTeamView
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
self=[super initWithCoder:aDecoder];
if (self)
{
[self customInit];
}
return self;
}
-(instancetype)initWithFrame:(CGRect)frame
{
self=[super initWithFrame:frame];
if (self)
{
[self customInit];
}
return self;
}
-(void)customInit
{
[[NSBundle mainBundle]loadNibNamed:#"AddTeamView" owner:self options:nil];
[self addSubview:self.contentView];
}
- (IBAction)okButton:(UIButton *)sender
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSDictionary *params = #{#"team_name":self.enterNameTextField.text
};
[manager POST:#"https://api.cartolafc.globo.com/times?q=team_name" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
}progress:nil success:^(NSURLSessionTask *task, id responseObject) {
// [self stopHud];
NSLog(#"JSON: %#", responseObject);
NSDictionary *response = (NSDictionary *)responseObject;
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSInteger statusCode = error.code;
NSLog(#"%ld",(long)statusCode);
// [self stopHud];
}];
}
I create a .Xib file like:
When I press on Ok button, the response doesn't come and nothing happens.
Now how can I declare custom Delegate for custom UIView
and why delegate is required here? Can anyone kindly explain what can I do to get the response of API?

Open your AddTeamView.h and this code.
#protocol AddTeamDelegate <NSObject>
- (IBAction)okButton:(UIButton *)sender;
#end
#property id <AddTeamDelegate> delegate;
And synthesize this property in AddTeamView.m file as below.
#synthesize delegate;
Add this code In your viewController.h file where you are adding AddTeamView as subview.
#interface ViewController : UIViewController <AddTeamDelegate>
In your viewController.m file add this code while adding AddTeamView as subView.
AddTeamView.delegate = self;
and add this method for Ok button in same file
- (IBAction)okButton:(UIButton *)sender
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSDictionary *params = #{#"team_name":self.enterNameTextField.text
};
[manager POST:#"https://api.cartolafc.globo.com/times?q=team_name" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
}progress:nil success:^(NSURLSessionTask *task, id responseObject) {
// [self stopHud];
NSLog(#"JSON: %#", responseObject);
NSDictionary *response = (NSDictionary *)responseObject;
} failure:^(NSURLSessionTask *operation, NSError *error) {
NSInteger statusCode = error.code;
NSLog(#"%ld",(long)statusCode);
// [self stopHud];
}];
}

Related

How to use CoreData in Xcode 8?

I am trying use CoreData, but when I add it to my project I only get two new methods :
- (NSPersistentContainer *)persistentContainer
and
- (void)saveContext
Now I can't get old methods to work with CoreData, and I can't find any tutorials with these new methods and Objective-C. How can I save and get data from CoreData using persistentContainer in Xcode 8 with Objective-c?
You can Get context as -
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
or as in Objective-C
NSManagedObjectContext *context = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).persistentContainer.viewContext;
And fetch data like -
var resultArray = try self.context.fetch(EntityName.fetchRequest())
or as in Objective-C
NSFetchRequest<EntityName *> *fetchRequest = [EntityName fetchRequest];
NSError *error ;
NSArray *resultArray= [context executeFetchRequest:fetchRequest error:&error];
And fetch data with sorting -
var resultArray = [EntityName]()
do {
let request : NSFetchRequest<EntityName> = EntityName.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "somekey", ascending: true)
let sortDescriptors = [sortDescriptor]
request.sortDescriptors = sortDescriptors
resultArray = try self.context.fetch(request)
} catch {
print("Error")
}
or as in Objective-C
NSFetchRequest<EntityName *> *fetchRequest = [EntityName fetchRequest];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"someKey" ascending:YES];
fetchRequest.sortDescriptors = #[sortDescriptor];
NSError *error ;
NSArray *resultArray= [context executeFetchRequest:fetchRequest error:&error];
And add data like -
let entityNameObj = EntityName(context: context)
entityNameObj.title = "title"
or as in Objective-C
NSManagedObject *entityNameObj = [NSEntityDescription insertNewObjectForEntityForName:#"EntityName" inManagedObjectContext:context];
[entityNameObj setValue:#"someValue" forKey:#"someKey"];
And save context like -
do {
try self.context.save()
} catch _ as NSError {
print("Error")
}
or as in Objective-C
[((AppDelegate*)[[UIApplication sharedApplication] delegate]) saveContext];
-(void)profileDatabase {
NSManagedObjectContext* context=[ADM.persistentContainer viewContext];
NSManagedObject *profile=[NSEntityDescription insertNewObjectForEntityForName:#"Profile" inManagedObjectContext:context];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"firstName"] forKey:#"firstName"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"surName"] forKey:#"surName"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"batchID"] forKey:#"batchID"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"profileImagePath"] forKey:#"profileImagePath"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"registeredEmail"] forKey:#"registeredEmail"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"role"] forKey:#"role"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"studentID"] forKey:#"studentID"];
NSLog(#"userObj:%#",profile);
NSError* error;
[context save:&error];
NSFetchRequest *fetchRequest=[[NSFetchRequest alloc]initWithEntityName:#"Profile"];
fetchRequest.returnsObjectsAsFaults=NO;
NSArray* results=[context executeFetchRequest:fetchRequest error:&error];
NSLog(#"Result:%#",results);
NSManagedObject *result=[results objectAtIndex:0];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"firstName"] forKey:#"firstName"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"surName"] forKey:#"surName"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"batchID"] forKey:#"batchID"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"profileImagePath"] forKey:#"profileImagePath"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"registeredEmail"] forKey:#"registeredEmail"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"role"] forKey:#"role"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"studentID"] forKey:#"studentID"];
NSLog(#"dic:%#",ADM.databaseResponseOfProfileDict);}
I have found a solution using Objective C. It runs, but I'm not sure that it is the correct solution.
- (void)dbManager {
NSManagedObjectContext *context = self.persistentContainer.viewContext;
NSError *error = nil;
if ([context hasChanges] && ![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, error.userInfo);
abort();
}
NSManagedObject *customAnimal = [NSEntityDescription insertNewObjectForEntityForName:#"Animals" inManagedObjectContext:context];
[customAnimal setValue:#"Lion" forKey:#"type"];
[customAnimal setValue:#"Rabit" forKey:#"name"];
[customAnimal setValue:#"Blue" forKey:#"color"];
[customAnimal setValue:#12 forKey:#"age"];
NSLog(#"Get data from DB");
NSMutableArray* animalsArray;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Animals"];
animalsArray = [[context executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSLog(#"array is %#", animalsArray); // array is (
"<Animals: 0x6000000aee80> (entity: Animals; id: 0x60000022e120 <x-coredata:///Animals/tAAC7332D-6BEF-441C-9041-0ECB57469FA62> ; data: {\n age = 12;\n color = Blue;\n name = Rabit;\n type = Lion;\n})"
}
For all the beginners out there, this will give you the basic idea.
welcome.m
==========
#import "welcomepage.h"
#import "Register.h"
#import "login.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "loginbtn.h"
#import "King+CoreDataProperties.h"
#interface welcomepage ()
{
AppDelegate *a;
NSManagedObjectContext *context;
}
#end
#implementation welcomepage
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (IBAction)login:(id)sender
{
loginbtn *lb=[[loginbtn alloc]init];
[self.navigationController pushViewController:lb animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)register:(id)sender
{
a=(AppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *context1=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
Student *ss=[NSEntityDescription insertNewObjectForEntityForName:#"Student" inManagedObjectContext:context1];
ss.name=[NSString stringWithFormat:#"%#",_txtfld1.text];
ss.age=[NSString stringWithFormat:#"%#",_txtfld2.text];
ss.place=[NSString stringWithFormat:#"%#",_txtfld3.text];
[a saveContext];
if (_txtfld1.text.length && _txtfld2.text.length && _txtfld3.text.length != 0)
{
UIAlertView *al=[[UIAlertView alloc]initWithTitle:#"THANK YOU" message:#"DATA SUCESSFULLY SAVER. YOU CAN LOGIN NOW WITH YOUR PASSWORD AND NAME" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[al show];
_txtfld1.text=#"";
_txtfld2.text=#"";
_txtfld3.text=#"";
Register *rg=[[Register alloc]init];
[self.navigationController pushViewController:rg animated:YES];
}
else
{
UIAlertView *al2=[[UIAlertView alloc]initWithTitle:#"WARRNING" message:#"PLEASE FILL THE DATA COMPLETELY" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[al2 show];
}
}
===================================================
Register.m
==========
#import "Register.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "welcomepage.h"
#interface Register ()<UITableViewDelegate,UITableViewDataSource>
{
AppDelegate *a;
NSManagedObjectContext *context01;
NSArray *array01;
}
#end
#implementation Register
- (void)viewDidLoad
{
[super viewDidLoad];
a=((AppDelegate *)[UIApplication sharedApplication].delegate);
context01=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
// specifying nsrequest and nsentity
NSFetchRequest *req=[[NSFetchRequest alloc]init];
NSEntityDescription *entity01=[NSEntityDescription entityForName:#"Student" inManagedObjectContext:context01];
[req setEntity:entity01];
// putting datas from reto array
NSError *err=nil;
array01=[context01 executeFetchRequest:req error:&err];
// Do any additional setup after loading the view from its nib.
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return array01.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ci=#"hai";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ci];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ci];
}
if (indexPath.row==0) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"name"];
}
if (indexPath.row==1) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"age"];
}
if (indexPath.row==2) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"place"];
}
return cell;
}
==================================================
Loginbtn.m
============
#import "loginbtn.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "login.h"
#interface loginbtn ()
{
AppDelegate *a;
NSArray *arraylb;
}
#end
#implementation loginbtn
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)lgbtn:(id)sender
{
a=(AppDelegate *)[UIApplication sharedApplication].delegate;
//xcode 8.2.1 specification code
NSManagedObjectContext *context=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
//creating feathch request and entity
NSFetchRequest *req=[[NSFetchRequest alloc]init];
NSEntityDescription *entity=[NSEntityDescription entityForName:#"Student" inManagedObjectContext:context];
[req setEntity:entity];
// setting predicate
NSPredicate *pre=[NSPredicate predicateWithFormat:#"age like %# and place like %#",_txt1.text,_txt2.text];
[req setPredicate:pre];
//creating error and array to store
NSError *err=nil;
arraylb=[[NSArray alloc]init];
arraylb=[context executeFetchRequest:req error:&err];
login *lg=[[login alloc]init];
if (arraylb.count!=0)
{
lg.array001=arraylb;
}
//
// if (arraylb.count!=0)
//// {
////
//// lv *lvi=[[lv alloc]init];
////
//// //passing value
//// lvi.array001=arraylb;
////
////
//// //lv.str1=self.tf1.text;
//// //lv.str2=self.tf2.text;
//// [self.navigationController pushViewController:lvi animated:YES];
////
////
//// }
//// else
//// {
//
// self.lb.text=#"Invalid username & password";
//
// }
//
[self.navigationController pushViewController:lg animated:YES];
}
=====================================================
Lohin.m
=========
#import "login.h"
#import "Student+CoreDataProperties.h"
#import "AppDelegate.h"
#import "loginbtn.h"
#interface login ()
{
AppDelegate *a;
NSArray *array01;
}
#end
#implementation login
- (void)viewDidLoad
{
[super viewDidLoad];
_txt11.text=[[_array001 objectAtIndex:0]valueForKey:#"name"];
_txt22.text=[[_array001 objectAtIndex:0]valueForKey:#"age"];
_txt33.text=[[_array001 objectAtIndex:0]valueForKey:#"place"];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
// Dispose of any resources that can be recreated.
}

My category table it is empty and I created some categories

I'm doing a system to find the application ads by category however after creating my table it is empty. I have created categories however they do not appear.
This is my categoriestableview:
#import "CategoriesTableViewController.h"
#import "AdViewController.h"
#import "JVWebService.h"
//#import "SearchViewController.h"
#define JVGrayCellColor [UIColor colorWithRed:236/255.0 green:240/255.0 blue:241/255.0 alpha:1]
#interface CategoriesTableViewController ()
#property (strong, nonatomic) NSArray *categoriesArray;
- (IBAction)search:(id)sender;
#end
#implementation CategoriesTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.shouldHaveMenuButton = YES;
}
#pragma mark - Data Source
- (NSArray *)categoriesArray {
if (_categoriesArray) return _categoriesArray;
return [NSArray arrayWithObjects:
#[#"celulares", #"mobile.png"],
#[#"tablets", #"tablet.png"],
#[#"eletrônicos", #"eletro.png"],
#[#"video-games", #"videogame.png"],
#[#"informática", #"monitor.png"],
#[#"esportes", #"runner.png"],
#[#"arte e lazer", #"paint.png"],
#[#"veículos", #"car.png"],
#[#"para a casa", #"house.png"],
#[#"roupas", #"shirt.png"],
#[#"bebês", #"baby.png"],
#[#"coisas", #"etc.png"],
nil];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.categoriesArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CategoryCell" forIndexPath:indexPath];
if (!cell) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CategoryCell"];
UILabel *categoryName = (UILabel *)[cell viewWithTag:10];
categoryName.text = [[self.categoriesArray objectAtIndex:indexPath.row][0] uppercaseString];
//
// UIImageView *categoryImage = (UIImageView *)[cell viewWithTag:20];
// categoryImage.image = [UIImage imageNamed:[self.categoriesArray objectAtIndex:indexPath.row][1]];
// categoryImage.contentMode = UIViewContentModeScaleAspectFit;
if (indexPath.row %2 != 0)
cell.backgroundColor = JVGrayCellColor;
else
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[[JVWebService sharedService] getAdsForCategory:indexPath.row];
AdViewController *adsVC = [[UIStoryboard storyboardWithName:#"Ad" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"AdViewController"];
[adsVC setLoading:YES];
[[JVWebService sharedService] setServiceDelegate:adsVC];
[self.navigationController pushViewController:adsVC animated:YES];
}
#pragma mark - Actions
//- (IBAction)search:(id)sender {
// SearchViewController *svc = [[UIStoryboard storyboardWithName:#"Search" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"SearchViewController"];
//
// [self.navigationController presentViewController:[[UINavigationController alloc] initWithRootViewController:svc]
// animated:YES
// completion:nil];
//}
#end
this is my WebService;
#import "JVWebService.h"
#import <RestKit/RestKit.h>
#import "AppDelegate.h"
#import "JVUtils.h"
#import "Ads.h"
#import "CategoriesTableViewController.h"
static NSString *kServerURL = #"http://localhost:3000";
#interface JVWebService ()
#property (strong, nonatomic) RKObjectManager *restKitObjectManager;
#end
#define kSuccessStatusCode RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
#implementation JVWebService
+ (instancetype)sharedService {
static JVWebService *sharedService = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedService = [[self alloc] init];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
sharedService.restKitObjectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:kServerURL]];
[sharedService.restKitObjectManager.HTTPClient setAuthorizationHeaderWithUsername:[[[AppDelegate sharedDelegate] currentUser] email]
password:[[[AppDelegate sharedDelegate] currentUser] password]];
});
return sharedService;
}
#pragma mark - User
- (void)getAdsFromCurrentUser {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:Ads.class];
[objectMapping addAttributeMappingsFromDictionary:self.adAttributes];
NSString *path = #"/my_ads.json";
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:#"ads"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
[self.restKitObjectManager getObjectsAtPath:path parameters:nil success:^(RKObjectRequestOperation *operation,
RKMappingResult *result){
if ([self.serviceDelegate respondsToSelector:#selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:result.array];
} failure:^(RKObjectRequestOperation *operation, NSError *error){
RKLogError(#"Operation failed with error: %#", error);
if ([self.serviceDelegate respondsToSelector:#selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (void)postAd:(Ads *)ad {
NSString *path = #"/ads.json";
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:Ads.class];
[objectMapping addAttributeMappingsFromDictionary:self.adAttributes];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:self.postAdAttributes];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:Ads.class
rootKeyPath:#"ad"
method:RKRequestMethodAny];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:#"ad"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addRequestDescriptor:requestDescriptor];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
NSMutableURLRequest *urlRequest = [self.restKitObjectManager multipartFormRequestWithObject:ad method:RKRequestMethodPOST path:path parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// NSArray *photosArray = ad.photos[0];
// for(int i = 0; i < photosArray.count; i++) {
//
// NSString *name = [NSString stringWithFormat:#"ad[photos_attributes][%i][picture]", i];
// NSString *fileName = [NSString stringWithFormat:#"photo%i.jpg", i];
// [formData appendPartWithFileData:UIImagePNGRepresentation(photosArray[i])
// name:name
// fileName:fileName
// mimeType:#"image/jpg"];
// }
}];
RKObjectRequestOperation *operation = [self.restKitObjectManager objectRequestOperationWithRequest:urlRequest
success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
if ([self.serviceDelegate respondsToSelector:#selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:nil];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
if ([self.serviceDelegate respondsToSelector:#selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager enqueueObjectRequestOperation:operation];
[self.restKitObjectManager removeRequestDescriptor:requestDescriptor];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (NSDictionary *)adAttributes {
return #{
#"id" : #"_id",
#"title" : #"title",
#"price" : #"price",
#"local" : #"local",
#"description" : #"especification",
#"categories" : #"categories",
#"photos" : #"photos",
#"latitude" : #"latitude",
#"longitude" : #"longitude"
};
}
- (void)getAdsForCategory:(CategoryType)type {
NSString *path = #"/category.json";
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:Ads.class];
[objectMapping addAttributeMappingsFromDictionary:self.adAttributes];
RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:User.class];
[userMapping addAttributeMappingsFromDictionary:self.userAttributes];
[objectMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"user"
toKeyPath:#"owner"
withMapping:userMapping]];
NSString *category = [self categoryStringForType:type];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:objectMapping
method:RKRequestMethodAny
pathPattern:path
keyPath:#"ads"
statusCodes:kSuccessStatusCode];
[self.restKitObjectManager addResponseDescriptor:responseDescriptor];
NSDictionary *params = #{#"name" : category};
[self.restKitObjectManager getObjectsAtPath:path parameters:params success:^(RKObjectRequestOperation *operation,
RKMappingResult *result){
if ([self.serviceDelegate respondsToSelector:#selector(successfulRequestDidReturnObject:)])
[self.serviceDelegate successfulRequestDidReturnObject:result.array];
} failure:^(RKObjectRequestOperation *operation, NSError *error){
RKLogError(#"Operation failed with error: %#", error);
if ([self.serviceDelegate respondsToSelector:#selector(requestDidFailWithError:)])
[self.serviceDelegate requestDidFailWithError:error];
}];
[self.restKitObjectManager removeResponseDescriptor:responseDescriptor];
}
- (NSString *)categoryStringForType:(CategoryType)type {
NSString *category;
switch (type) {
case CategoryTypeCellphones: category = #"Celulares"; break;
case CategoryTypeTablets: category = #"Tablets"; break;
case CategoryTypeElectronics: category = #"Eletronicos"; break;
case CategoryTypeVideogames: category = #"Video-Games"; break;
case CategoryTypeComputers: category = #"Informatica"; break;
case CategoryTypeSports: category = #"Esportes"; break;
case CategoryTypeHobbies: category = #"Arte e Lazer"; break;
case CategoryTypeVehicles: category = #"Veiculos"; break;
case CategoryTypeForHouse: category = #"Para Casa"; break;
case CategoryTypeClothes: category = #"Roupas"; break;
case CategoryTypeBabies: category = #"Bebes"; break;
case CategoryTypeOtherStuffs: category = #"Coisas"; break;
}
return category;
}
- (NSDictionary *)postAdAttributes {
return #{
#"_id" : #"id",
#"title" : #"title",
#"price" : #"price",
#"local" : #"local",
#"especification" : #"description",
#"categories" : #"category_ids",
#"user_id" : #"user_id",
#"latitude" : #"latitude",
#"longitude" : #"longitude"
};
}
- (NSDictionary *)userAttributes {
return #{
#"id" : #"_id",
#"email" : #"email",
#"name" : #"name",
#"avatar" : #"profileImageUrl",
#"phone" : #"phone",
#"password" : #"password",
#"contact_pref" : #"communicationPreference",
#"products_alerts" : #"productsAlerts"
};
}
- (NSDictionary *)postUserAttributes {
return #{
#"_id" : #"id",
#"email" : #"email",
#"name" : #"name",
#"phone" : #"phone",
#"password" : #"password",
#"password" : #"password_confirmation",
#"communicationPreference" : #"contact_pref"
};
}
#end
TableView's require a datasource and a delegate (a class that provides the tableViews data and delegate methods).
This can be done in the storyboard or in code like so:
- (void)viewDidLoad {
[super viewDidLoad];
self.shouldHaveMenuButton = YES;
self.tableView.delegate = self;
self.tableView.datasource = self;
}

variable becomes nil in numberOfRowsInTableView after being set in another method

My class looks like this :
#interface ApplicantPickerController : AppPage <NSTableViewDataSource, NSTableViewDelegate>
{
School *school;
__weak IBOutlet NSTableView *tableView;
NSMutableArray *familyList;
__weak IBOutlet NSProgressIndicator *progressIndicator;
}
- (IBAction)alphabetButtonPressed:(id)sender;
#end
In the alphabetButtonPressed method, I'm fetching a json array from a webservice and assigning it to familyList. After doing this, I do [tableView reload];
When the control passes to the - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView method, familyList becomes nil. Why is this happening and how can I fix it?
I'm using ARC for this project.
Cocoa/Objective-C newbie here. Any help would be much appreciated. Thank you!
Updated - Here is the implementation of the class :
#interface ApplicantPickerController ()
#end
#implementation ApplicantPickerController
- (IBAction)alphabetButtonPressed:(id)sender {
[progressIndicator startAnimation:self];
NSString * addy = [[NSString alloc] initWithFormat:#"%#.php?function=applicant_lookup&schoolID=%#&alpha=%#&currentYear=%#&format=json", BASE_URL_SCHOOL, school->recordID, [sender title], school->CurrentYear];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:addy]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if(data) {
//NSString * resp = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *error = nil;
NSObject *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if([json isKindOfClass:[NSDictionary class]])
{
familyList = nil;
[tableView reloadData];
}
else if ([json isKindOfClass:[NSArray class]])
{
familyList = [[NSMutableArray alloc] init];
[familyList addObjectsFromArray:(NSArray*)json];
//[_familyList retain];
[tableView reloadData];
}
[progressIndicator stopAnimation:self];
}
}];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [familyList count];
}
- (id)initWithMainView:(NSView *)_theView AndMainController:(NSViewController *)_theViewController AndNibName:(NSString *)nibName AndArgs:(NSArray *)_args
{
self = [super initWithMainView:_theView AndMainController:_theViewController AndNibName:nibName AndArgs:_args];
school = [args objectAtIndex:0];
return self;
}
#end
I don't know if I discovered a bug by apple, but following is how I solved this issue.
I was setting the NSTableView delegate and datasource in the UI builder (by right clicking and making the connections with the mouse). For some reason, if I set the delegate and dataSource in the code (specifically in the awakeFromNib method), the issue gets resolved.
- (void)awakeFromNib {
tableView.delegate = self;
tableView.dataSource = self;
}

Access properties and methods from one class inside another class in Objective C

I am trying to build a class in Objective C that contain serve the web service and database methods for my application. In this class I want to call a web service and grab employee records and then load them into an SQL table for later use in a view.
I got this working when all the code as in the view, but in trying to make this new class (what I am calling GetEmployee) I am running into problems. I do not understand well how to access properties and methods from one class in another.
Here is my GetEmployee Class
#import <Foundation/Foundation.h>
#import "employee.h"
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
#import "FMDatabasePool.h"
#import "FMDatabaseQueue.h"
#import "FMResultSet.h"
#import "Utility.h"
#interface GetEmployee : NSObject
{
NSMutableArray *employees;
}
#property (nonatomic, copy) NSString *databaseName;
#property (nonatomic, copy) NSString *databasePath;
- (void)updateEmployeeData;
- (void)callWebService;
- (void)fetchedData:(NSData *)responseData;
- (NSMutableArray *) getEmployees;
#end
implementation
#define kBgQueue dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define scoularDirectoryURL [NSURL URLWithString: #"https://XXXXXXXXX/mobile/mobilede.nsf/restServices.xsp/PeopleByName"]
#import "GetEmployee.h"
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
#import "FMResultSet.h"
#implementation GetEmployee
- (id) init
{
if (self = [super init])
{
self.databaseName = #"employees.db";
}
return self;
}
#pragma
- (void)updateEmployeeData{
//Delete database if it exists and then copy fresh DB
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
self.databasePath = [documentDir stringByAppendingPathComponent:self.databaseName];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL success;
success = [fileManager fileExistsAtPath:self.databasePath];
if (success) {
[fileManager removeItemAtPath:self.databasePath error:nil];
}
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];
//Call the web service
[self callWebService];
[self populateDatabase];
}
- (void) callWebService {
dispatch_sync(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
scoularDirectoryURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSMutableArray *jsonArray = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &error];
id jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
employees = [[NSMutableArray alloc] init];
if (!jsonArray) {
} else {
for (jsonObject in jsonArray){
employee *thisEmployee = [employee new];
thisEmployee.fullName = [jsonObject objectForKey:#"$13"];
thisEmployee.ste = [jsonObject objectForKey:#"state"];
thisEmployee.city = [jsonObject objectForKey:#"city"];
[employees addObject:thisEmployee];
}
}
}
-(void) populateDatabase {
////Call the web service and populate the db
//dispatch_sync(kBgQueue, ^{
// NSData* data = [NSData dataWithContentsOfURL:
// scoularDirectoryURL];
// [self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
//});
//Populate the db
FMDatabase *db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
[db open];
for (employee *thisemployee in employees) {
BOOL success = [db executeUpdate:#"INSERT INTO employees (fullname,city,state) VALUES (?,?,?);",thisemployee.fullName,thisemployee.city,thisemployee.ste, nil];
if (success) {} // Only to remove success error
}
[db close];
}
- (NSMutableArray *) getEmployees
{
//NSMutableArray *employees = [[NSMutableArray alloc] init];
employees = [[NSMutableArray alloc] init];
FMDatabase *db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
[db open];
FMResultSet *results = [db executeQuery:#"SELECT * FROM employees"];
while([results next])
{
employee *thisEmployee = [employee new];
thisEmployee.fullName = [results stringForColumn:#"fullname"];
thisEmployee.city = [results stringForColumn:#"city"];
thisEmployee.ste = [results stringForColumn:#"state"];
[employees addObject:thisEmployee];
}
[db close];
return employees;
}
#end
And here is the MasterViewController
header
#import <UIKit/UIKit.h>
#import "employee.h"
#import "FMDatabase.h"
#import "FMResultSet.h"
#import "FMDatabaseAdditions.h"
#import "Utility.h"
#import "GetEmployee.h"
#interface MasterViewController : UITableViewController
{
NSMutableArray *employees;
//GetEmployee *ScoularEmployees;
}
#end
implementation
#define kBgQueue dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define scoularDirectoryURL [NSURL URLWithString: #"https://xxxxxxxx/mobile/mobilede.nsf/restServices.xsp/PeopleByName"]
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "employee.h"
#import "GetEmployee.h"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#property(strong, nonatomic) GetEmployee *ScoularEmployees;
#end
#implementation MasterViewController
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
//GetEmployee *ScoularEmployees = [[GetEmployee alloc] init];
[self.ScoularEmployees init];
//[self.ScoularEmployees init];
//_ScoularEmployees = [[GetEmployee alloc] init];
//[_ScoularEmployees getEmployees];
//GetEmployee *ScoularEmployees = [[GetEmployee alloc] init];
//GetEmployee *thisEmployeeData = [[GetEmployee alloc] init];
//[self.ScoularEmployees updateEmployeeData];
//[self.ScoularEmployees getEmployees];
//[ScoularEmployees updateEmployeeData];
//[ScoularEmployees getEmployees];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return employees.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *fullName = [[employees objectAtIndex:indexPath.row] valueForKey:#"fullName"];
cell.textLabel.text = fullName;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
employee *dtlEmployee = [employees objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:dtlEmployee];
}
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSMutableArray *jsonArray = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &error];
id jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
//employees = [[NSMutableArray alloc] init];
if (!jsonArray) {
} else {
//NSMutableArray *employees = [[NSMutableArray alloc ]init];
for (jsonObject in jsonArray){
employee *thisEmployee = [employee new];
thisEmployee.fullName = [jsonObject objectForKey:#"$13"];
thisEmployee.ste = [jsonObject objectForKey:#"state"];
thisEmployee.city = [jsonObject objectForKey:#"city"];
[employees addObject:thisEmployee];
}
}
}
//-(NSMutableArray *) getEmployees
//{
//NSMutableArray *employees = [[NSMutableArray alloc] init];
//employees = [[NSMutableArray alloc] init];
// FMDatabase *db = [FMDatabase databaseWithPath:[Utility getDatabasePath]];
// [db open];
// FMResultSet *results = [db executeQuery:#"SELECT * FROM employees"];
//
// while([results next])
// {
// employee *thisEmployee = [employee new];
// thisEmployee.fullName = [results stringForColumn:#"fullname"];
// thisEmployee.city = [results stringForColumn:#"city"];
// thisEmployee.ste = [results stringForColumn:#"state"];
// //[employees addObject:thisEmployee];
// }
//
// [db close];
//
// return employees;
// return true;
//}
#end
Any help would be greatly appreciated.
I thought it was clear but I can see it is not. In the view class I want to be able to load an NSMutableArray called *employees that comes from the SQLLite database and out them on the screen. I have tried to centralize the code for data access in the GetEmployee class. Everything in that class deals with the data - web service, load the data to the database, and getting the data out of the database as well. So in that Class I have a method "getEmployees" that gets data from the db and loads it into that NSMutableArry. So here is the problem, in the class I cannot get access to the methods or properties in GetEmpployee. That is my question.
Without reading through all the code you've posted...
For using a Class method, the syntax is:
[ClassName methodName];
[ClassName anotherMethod:withArguments];
Methods that are called using this syntax will look like this in the corresponding .h file:
+(void)methodName;
+(void)anotherMethod:(NSNumber*)number;
For using an instance method, the syntax is:
ClassName myObj = [[ClassName alloc] init];
[myObj someMethod];
[myObj someOtherMethod:withArguments];
Methods that are called using this syntax will look like this in the corresponding .h file:
-(void)someMethod;
-(void)someOtherMethod:(NSString*)parameter;

Chaining MKNetworkKit API calls and having problems with how to populate an NSMutableArray with the data

I have a UITableView with two sections, where each section needs a call to a REST API for the data. I'm using MKNetworkKit for the calls. My question is how I should populate the NSMutableArray for the UITableView in order to ensure that the data is correct at all times, even after a "Pull to refresh". I just feel that I'm going about this all wrong.
This is my code as of now:
MKNetworkEngine subclass (.h):
typedef void (^DualResponseBlock)(id ResponseJson, NSError *);
-(MKNetworkOperation*) RequestWithURI:(NSString *) URI
withHandler:(DualResponseBlock)ResponseBlock;
MKNetworkEngine subclass (.m):
-(MKNetworkOperation *)RequestWithURI:(NSString *)URI
withHandler:(DualResponseBlock)ResponseBlock {
MKNetworkOperation *op = [self operationWithPath:HubAPI(URI)
params:nil
httpMethod:#"GET"];
if(![self isReachable]) {
DLog(#"Unable to connect to %# - Reachability is %d", HubAPI(URI), [self isReachable]);
}
[op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
[completedOperation responseJSONWithCompletionHandler:^(id jsonObject) {
ResponseBlock(jsonObject, nil);
}];
} errorHandler:^(MKNetworkOperation *errorOp, NSError *error) {
[errorOp responseJSONWithCompletionHandler:^(id jsonObject) {
NSMutableDictionary *errorDetails = [NSMutableDictionary dictionary];
NSDictionary *errorResponse = [jsonObject objectForKey:#"error"];
[errorDetails setValue:[errorResponse objectForKey:#"message"] forKey:NSLocalizedDescriptionKey];
NSError *error = [NSError errorWithDomain:kNSErrorDomain code:[[errorResponse objectForKey:#"code"] intValue] userInfo:errorDetails];
ResponseBlock(nil, error);
}];
}];
[self enqueueOperation:op];
return op;
}
ViewController with UITableView (.h):
#interface WishlistViewController : UITableViewController <NSObject, UITableViewDelegate, UITableViewDataSource, UIActionSheetDelegate> {
NSMutableArray *wishlist;
}
#property (nonatomic, retain) IBOutlet UITableView *wishlistTableView;
ViewController with UITableView (-(void)viewDidLoad) (.m):
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
[app.hubEngine RequestWithURI:#"wishlist" withHandler:^(id responseJson, NSError *responseError) {
if(responseJson != nil) {
wishlist = [[NSMutableArray alloc] initWithObjects:[responseJson mutableCopy], nil];
[app.hubEngine RequestWithURI:#"wishlist/granted" withHandler:^(id responseJson, NSError *responseError) {
if(responseJson != nil) {
[wishlist addObject:[responseJson mutableCopy]];
[_wishlistTableView reloadData];
}
else {
DLog(#"Error: %#", [responseError localizedDescription]);
}
[MBProgressHUD hideHUDForView:self.view animated:YES];
}];
}
else {
DLog(#"Error: %#", [responseError localizedDescription]);
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
}];
Not exactly sure what you are trying to do here, but if you want the second operation to be executed after the first completes, try this.
[op2 addDependency:op1];