0

i'm having a viewcontroller which has show segue to next view controller

but for each button which connected to show segue having webservice to call and response from webservice is storing in plist file and accessing in next view

my issue:when i click on button it is directly going to nextview without loading plist contents first time but when i'm go back and click on button it is showing plist contents

any help most appreciated

here is my plist creation code it is creating well but after the button click

if(connection == conn1)
{
          NSError *e = nil;

    classResponse = [NSJSONSerialization JSONObjectWithData:classData options:NSJSONReadingMutableLeaves error:&e];
    NSError *error;

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"classesArray.plist"];

    NSLog(@"file path is %@ ",path);

    NSFileManager *fileManager=[NSFileManager defaultManager];

    if(![fileManager fileExistsAtPath:path])
    {

        NSString *bundle = [[[NSBundle mainBundle]resourcePath]stringByAppendingString:@"classesArray.plist"];

        //NSString *bundle = [[NSBundle mainBundle]pathForResource:@"create" ofType:@"plist"];

        [fileManager copyItemAtPath:bundle toPath:path error:&error];
     }
    [classResponse writeToFile:path atomically:YES];


}

i'm using tableview with custom cell in next view to load from plist here is my code

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
    return [className count];
 }

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath    *)indexPath
  {
    static NSString *CellIdentifier = @"cellId";
    classesTeacher *cell = [tableView
                            dequeueReusableCellWithIdentifier:CellIdentifier
                            forIndexPath:indexPath];


    if (cell == nil) {

        cell = [[classesTeacher alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    }

    long row = [indexPath row];

    cell.classname.text = className[row];
    cell.classdescription.text = classDescription[row];
    cell.classCode.text = classRef[row];
    cell.studentcount.text=classIds[row];

    return cell;  
}

- (void)viewDidLoad {
    [super viewDidLoad];


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];

   NSString *path = [documentsDirectory stringByAppendingPathComponent:@"classesArray.plist"];


    NSDictionary *StudentDict=[[NSDictionary alloc]initWithContentsOfFile:path];

   // NSLog(@" QuizDict has %@ ",StudentDict);

    //get all values for a key in array

    NSArray *See = StudentDict[@"alldata"];

    className= [See valueForKey:@"class_name"];
    classDescription=[See valueForKey:@"class_description"];
    classRef=[See valueForKey:@"class_ref"];
    classIds=[See valueForKey:@"number_of_students"];
    //classId = [See objectAtIndex:@"classid"];
    NSLog(@"class id %@",classId);

    NSLog(@"class id is %@",classIds);

    UIImage *backImage = [UIImage imageNamed:@"s-left-arrow.png"];
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    backButton.frame = CGRectMake(0, 0, backImage.size.width, backImage.size.height);

    [backButton setImage:backImage forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(pushBackButton:)    forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton] ;

    self.navigationItem.hidesBackButton = YES;
    self.navigationItem.leftBarButtonItem = backBarButtonItem;
    [self.table reloadData];
        // Do any additional setup after loading the view.
}
Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
  • You'll need to show some code. – Marcus Adams Dec 16 '14 at 13:58
  • Probably you call is asynchronous, it's for that your viewController doesn't have the plist at first. You should implement a call back from your web service to update your view controller. Or (worse) stop your app (the viewController) until the web service finish. – Onik IV Dec 16 '14 at 14:09
  • @OnikIV i'm using nsurl connection how to implement call back from webservice – user3595019 Dec 16 '14 at 14:15
  • NSURLConnection could be used in both, but usually all API request are asynchronous. If you put here the code of your viewController (at least, the part what catch data from your plist). I can write an answer with a call back (base on Notification Center). – Onik IV Dec 16 '14 at 14:19

1 Answers1

1

This sends up a red flag for me, I don't understand why you would be storing data in a plist and accessing it later unless you are using this as a way to pass data between the two views.

Regardless - if the data is not available when you need it at transition time then you have a few choices: 1 - get the data before you transition to the new view. This will require that you hold up the transition until the data is returned; 2 - get the data after you transition to the new view. This will require that you pass enough data to the new view that it can make the request.

Need to be very careful with option 1. If you start a request and then transition to the new view the view controller for the first view will go out of scope leaving the return data with no where to go and possibly calling a method that no longer exists (app crash).

Here is a good article (one of many) on callbacks and delegates. delegate function vs callback function

This can go in either the first or second view controller depending on when you decide to get the data.

If you put it in the first view controller you will want to change your segue and have it trigger manually rather than in the storyboard on the button. You will still create a segue in the storyboard but it will not be assigned to the button. Assign it generically to the view and be sure to give it a storyboard name so it can be referenced later. Re assign the button action to trigger the download. In the completion block for your callback (or in the delegate method) call the segue manually once the data has returned.

[self performSegueWithIdentifier: @"YourSegueName" sender: self];

If you decide to request the data in the second view controller then you can use the prepare for segue method to pass enough data to this method to complete the data request

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if([segue.identifier isEqualToString:@"YourSegueName"]) {
        YourSecondVC *secondVC = (YourSecondVC *)segue.destinationViewController;
        secondVC.dataForRequest= @"request this data;
    }

This assumes your second view controller declares an NSString variable named "dataForRequest" Because the second view controller has been created by the system at this point you can use this to assign data to it's member objects even if they are a complex data type.

Community
  • 1
  • 1
Mr. Soccer
  • 306
  • 1
  • 2
  • is it good way to store json response data in plist to access in nextview give me some suggestions i'm not out of this problem – user3595019 Dec 17 '14 at 07:57