কীভাবে এনএসজেএসএসনারাইজেশন ব্যবহার করবেন


156

আমার কাছে একটি জেএসএন স্ট্রিং রয়েছে (পিএইচপি'র থেকে json_encode()এটি দেখতে দেখতে:

[{"id": "1", "name":"Aaa"}, {"id": "2", "name":"Bbb"}]

আমি আমার আইফোন অ্যাপ্লিকেশনটির জন্য এটি কোনও ধরণের ডেটা স্ট্রাকচারে পার্স করতে চাই। আমি ভাল জিনিস অনুমান আমাকে অভিধান একটি অ্যারে আছে হবে জন্য, তাই অ্যারের মধ্যে 0th উপাদান কী এর মাধ্যমে একটি অভিধান হল "id" => "1"এবং "name" => "Aaa"

কিভাবে NSJSONSerializationডেটা সঞ্চয় করে তা আমি বুঝতে পারি না । এই পর্যন্ত আমার কোড এখানে:

NSError *e = nil;
NSDictionary *JSON = [NSJSONSerialization 
    JSONObjectWithData: data 
    options: NSJSONReadingMutableContainers 
    error: &e];

এটি কেবলমাত্র অন্য একটি ওয়েবসাইটে উদাহরণ হিসাবে দেখেছি। আমি JSONউপাদানগুলির সংখ্যা এবং এর মতো জিনিসগুলি মুদ্রণের মাধ্যমে অবজেক্টে একটি পঠন করার চেষ্টা করছি, তবে আমি সবসময় পাচ্ছি EXC_BAD_ACCESS

আমি NSJSONSerializationউপরের জেএসওনকে বিশ্লেষণ করতে কীভাবে ব্যবহার করব এবং আমি উল্লিখিত ডেটা স্ট্রাকচারে এটিকে রূপান্তর করব?


আপনার ডেটা ভেরিয়েবল সম্ভবত শূন্য
d.lebedav

এটা না, আমি ইতিমধ্যে এটি পরীক্ষা করেছি।
লোগান সারমান 13

আপনি কি ত্রুটি অবজেক্টে কোনও প্রাসঙ্গিক তথ্য আছে কিনা তা দেখার চেষ্টা করেছেন?
মনোলো

উত্তর:


214

আপনার রুট জসন অবজেক্টটি অভিধান নয় বরং একটি অ্যারে:

[{"id": "1", "name":"Aaa"}, {"id": "2", "name":"Bbb"}]

এটি আপনাকে কীভাবে এটি পরিচালনা করতে হবে তার একটি পরিষ্কার চিত্র দিতে পারে:

NSError *e = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableContainers error: &e];

if (!jsonArray) {
  NSLog(@"Error parsing JSON: %@", e);
} else {
   for(NSDictionary *item in jsonArray) {
      NSLog(@"Item: %@", item);
   }
}

ধন্যবাদ আমি চেষ্টা করব, তবে [JSON count]আমাকে কেবল EXC_BAD_ACCESS দেওয়ার পরিবর্তে কোনও কিছু ফিরিয়ে দেওয়া উচিত নয় ?
লোগান সারমান 13

এটি হওয়া উচিত, কেন আমি চেকটি যুক্ত করেছিলাম !jsonArrayএবং ত্রুটিটি প্রিন্ট করেছিলাম । পার্সিং চলাকালীন যে কোনও ত্রুটি এটি প্রদর্শিত হবে।
rckoenes

1
@ xs2bush না, যেহেতু আপনি jsonArrayএটি তৈরি করেননি এটি অটোরিলেজ হওয়া উচিত।
rckoenes

@ লোগান: হ্যাঁ, [জেএসএন কাউন্ট] এর একটি মান ফেরত দেওয়া উচিত। জম্বি সম্পর্কিত নীচে আমার উত্তর দেখুন। EXC_BAD_ACCESS প্রায় সর্বদা জম্বি-সম্পর্কিত।
অলি

এই ক্ষেত্রে, আইটেমটি প্রদত্ত জেএসওএন কী মান জোড়ের চাবিকাঠি .. আপনার লুপটি আমার প্রতিটি জেএসএন কী পুরোপুরি আউটপুট তৈরি করে। তবে আমি যে মানটি চান তার মূল কীটি ইতিমধ্যে আমি জানি ' এই কীটির মান পেতে এবং লগতে এটি আউটপুট দেওয়ার জন্য আমার প্রচেষ্টা ব্যর্থ হয়েছে। আর কোন অন্তর্দৃষ্টি?
থমাস ক্লোয়েস

75

প্রাপ্ত জেসনটি একটি অ্যারে বা অভিধান কিনা তা যাচাই করার জন্য এটি আমার কোড:

NSError *jsonError = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&jsonError];

if ([jsonObject isKindOfClass:[NSArray class]]) {
    NSLog(@"its an array!");
    NSArray *jsonArray = (NSArray *)jsonObject;
    NSLog(@"jsonArray - %@",jsonArray);
}
else {
    NSLog(@"its probably a dictionary");
    NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;
    NSLog(@"jsonDictionary - %@",jsonDictionary);
}

বিকল্পগুলির জন্য আমি এটি ব্যবহার করে দেখেছি: কেএনলঅপশন এবং এনএসজেএসআরআরইডিংমিউটেবল কনটেনার এবং উভয়ের জন্য সঠিকভাবে কাজ করে।

স্পষ্টতই, আসল কোডটি এইভাবে হতে পারে না যেখানে আমি যদি-অন্য ব্লকের মধ্যে এনএসআরাই বা এনএসডি অভিধান পয়েন্টার তৈরি করি।


29

এটা আমার জন্য কাজ করে. আপনার dataঅবজেক্ট সম্ভবত nilএবং যেমন রকোইনস উল্লেখ করেছে, মূল বস্তুটি (পরিবর্তনযোগ্য) অ্যারে হওয়া উচিত। এই কোডটি দেখুন:

NSString *jsonString = @"[{\"id\": \"1\", \"name\":\"Aaa\"}, {\"id\": \"2\", \"name\":\"Bbb\"}]";
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *e = nil;
NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&e];
NSLog(@"%@", json);

(ব্যাকস্ল্যাশ সহ জেএসএন স্ট্রিংয়ের উদ্ধৃতিগুলি আমাকে এড়িয়ে যেতে হয়েছিল))


9

আপনার কোড বলে মনে হয় ফলাফলের ব্যতীত জরিমানা একটি হল NSArray, কোনোNSDictionary , এখানে একটি উদাহরণ আছে:

প্রথম দুটি লাইন কেবল জেএসএন দিয়ে একটি ডেটা অবজেক্ট তৈরি করে, আপনি নেট থেকে এটি পড়তে পারাতে পারেন।

NSString *jsonString = @"[{\"id\": \"1\", \"name\":\"Aaa\"}, {\"id\": \"2\", \"name\":\"Bbb\"}]";
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];

NSError *e;
NSMutableArray *jsonList = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&e];
NSLog(@"jsonList: %@", jsonList);

এনএসলগ বিষয়বস্তু (অভিধানের একটি তালিকা):

jsonList: (
           {
               id = 1;
               name = Aaa;
           },
           {
               id = 2;
               name = Bbb;
           }
           )

এই বিকল্পটির অর্থ কী (এনএসজেএসআনআরআইডিংমুটেবল কনটেনারস)। আমি কেনিলোপশন করি না এবং সবকিছু ঠিকঠাক কাজ করে। এই বিকল্পগুলি ব্যবহারের উদ্দেশ্য আমাকে বলুন
জার ই আহমর

গুগলে শীর্ষে হিট NSJSONReadingMutableLeaves: "JSON অবজেক্ট গ্রাফের লিফ স্ট্রিংগুলি NSMutableString এর উদাহরণ হিসাবে তৈরি হয়েছে তা নির্দিষ্ট করে।"
জাফ

এবং মিউটেবল কনটেনার সম্পর্কে
জার ই

ওফস, আবার শীর্ষ গুগলের ফলাফল থেকে NSJSONReadingMutableContainers:: "অ্যারে এবং অভিধানগুলি পারস্পরিক পরিবর্তনযোগ্য বস্তু হিসাবে তৈরি করা হয়েছে তা নির্দিষ্ট করে" "
জাফ

1
আপনি কেবল ফিরে আসা JSON অবজেক্টটি সংশোধন করে এবং এটি সংরক্ষণ করতে চাইলে কেবলমাত্র এগুলি সহায়তা করে। উভয় ক্ষেত্রেই, বস্তুগুলি সম্ভবত স্বাবলম্বিত বস্তু এবং এটিই মূল কারণ বলে মনে হয়।
দীপক জিএম

6
[{"id": "1", "name":"Aaa"}, {"id": "2", "name":"Bbb"}]

উপরের জেএসওএন ডেটাতে, আপনি দেখিয়ে দিচ্ছেন যে আমাদের কাছে অভিধানের সংখ্যাটি বিভক্ত করে একটি অ্যারে রয়েছে।

পার্স করার জন্য আপনাকে এই কোডটি ব্যবহার করতে হবে:

NSError *e = nil;
NSArray *JSONarray = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableContainers error: &e];
        for(int i=0;i<[JSONarray count];i++)
        {
            NSLog(@"%@",[[JSONarray objectAtIndex:i]objectForKey:@"id"]);
             NSLog(@"%@",[[JSONarray objectAtIndex:i]objectForKey:@"name"]);
        }

3/3 + সুইফ্টের জন্য

   //Pass The response data & get the Array
    let jsonData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [AnyObject]
    print(jsonData)
    // considering we are going to get array of dictionary from url

    for  item  in jsonData {
        let dictInfo = item as! [String:AnyObject]
        print(dictInfo["id"])
        print(dictInfo["name"])
    }

3

নিম্নলিখিত কোডটি একটি ওয়েবসার্ভার থেকে একটি JSON অবজেক্ট এনেছে এবং এটি একটি এনএসডিকোরিয়ানে পার্স করে। আমি ওপেনওয়াদারম্যাপ এপিআই ব্যবহার করেছি যা এই উদাহরণের জন্য একটি সাধারণ জেএসএন প্রতিক্রিয়া দেয় returns এটি সহজ রাখার জন্য, এই কোডটি সিঙ্ক্রোনাস অনুরোধগুলি ব্যবহার করে।

   NSString *urlString   = @"http://api.openweathermap.org/data/2.5/weather?q=London,uk"; // The Openweathermap JSON responder
   NSURL *url            = [[NSURL alloc]initWithString:urlString];
   NSURLRequest *request = [NSURLRequest requestWithURL:url];
   NSURLResponse *response;
   NSData *GETReply      = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
   NSDictionary *res     = [NSJSONSerialization JSONObjectWithData:GETReply options:NSJSONReadingMutableLeaves|| NSJSONReadingMutableContainers error:nil];
   Nslog(@"%@",res);

আমি মনে করি আপনার উত্তরটি সেরা উত্তর হওয়া উচিত কারণ এটি JSON কাঠামোটি অ্যাক্সেস করার দ্রুততম উপায় বলে মনে হচ্ছে।
পোরিজম

2
অপশন দুটি ব্যবহার করা উচিত নয় তবে একক | যেহেতু তাদের বিটওয়াইড করা দরকার be
দীপক জিএম

নেটওয়ার্ক অনুরোধগুলির বিষয়ে প্রশ্নটি কিছু জিজ্ঞাসা করে না
নোহ গিলমোর

2

JrON স্ট্রিং থেকে কীভাবে আপনার ডেটা সঠিকভাবে পাবেন তা @ রেকোইনস ইতিমধ্যে আপনাকে দেখিয়েছে।

আপনি যে প্রশ্নটি জিজ্ঞাসা করেছেন: EXC_BAD_ACCESSপ্রায়শই সর্বদা আসে যখন আপনি কোনও বিষয় [অটো-] প্রকাশের পরে অ্যাক্সেস করার চেষ্টা করেন। এটি জেএসএন [ডি-] সিরিয়ালাইজেশনের জন্য নির্দিষ্ট নয় তবে এটি কেবল আপনাকে কোনও অবজেক্ট পাওয়ার সাথে সাথে এটি প্রকাশের পরে এটি অ্যাক্সেস করার সাথে সম্পর্কযুক্ত। এটি জেএসএনের মাধ্যমে এসেছিল তা বিবেচ্য নয়।

এটির ডিবাগ কীভাবে করা যায় তার বর্ণনা দেওয়ার জন্য অনেকগুলি পৃষ্ঠা রয়েছে - আপনি গুগল (বা এসও) obj-c zombie objectsএবং বিশেষত NSZombieEnabled, যা আপনার জম্বি বস্তুর উত্স নির্ধারণে সহায়তা করার ক্ষেত্রে অমূল্য প্রমাণ করবে তা করতে চান। ("জুম্বো" হ'ল একে বলা হয় যখন আপনি কোনও বস্তু প্রকাশ করেন তবে এটিতে একটি নির্দেশক রাখুন এবং পরে এটি উল্লেখ করার চেষ্টা করুন))


1

ডো / ট্রাই / ক্যাচ ব্লক সহ এক্সকোড 7 (বিটা) এ সুইফট 2.0

// MARK: NSURLConnectionDataDelegate

func connectionDidFinishLoading(connection:NSURLConnection) {
  do {
    if let response:NSDictionary = try NSJSONSerialization.JSONObjectWithData(receivedData, options:NSJSONReadingOptions.MutableContainers) as? Dictionary<String, AnyObject> {
      print(response)
    } else {
      print("Failed...")
    }
  } catch let serializationError as NSError {
    print(serializationError)
  }
}

1

দ্রষ্টব্য: সুইফ্ট 3 এর জন্য । আপনার JSON স্ট্রিং অভিধানের পরিবর্তে অ্যারে ফিরছে। নিম্নলিখিত চেষ্টা করুন:

        //Your JSON String to be parsed
        let jsonString = "[{\"id\": \"1\", \"name\":\"Aaa\"}, {\"id\": \"2\", \"name\":\"Bbb\"}]";

        //Converting Json String to NSData
        let data = jsonString.data(using: .utf8)

        do {

            //Parsing data & get the Array
            let jsonData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [AnyObject]

            //Print the whole array object
            print(jsonData)

            //Get the first object of the Array
            let firstPerson = jsonData[0] as! [String:Any]

            //Looping the (key,value) of first object
            for (key, value) in firstPerson {
                //Print the (key,value)
                print("\(key) - \(value) ")
            }

        } catch let error as NSError {
            //Print the error
            print(error)
        }

0
#import "homeViewController.h"
#import "detailViewController.h"

@interface homeViewController ()

@end

@implementation homeViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView.frame = CGRectMake(0, 20, 320, 548);
    self.title=@"Jason Assignment";

    // 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 clientServerCommunication];
}

-(void)clientServerCommunication
{
    NSURL *url = [NSURL URLWithString:@"http://182.72.122.106/iphonetest/getTheData.php"];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:req delegate:self];
    if (connection)
    {
        webData = [[NSMutableData alloc]init];
    }
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [webData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [webData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];

    /*Third party API
     NSString *respStr = [[NSString alloc]initWithData:webData encoding:NSUTF8StringEncoding];
     SBJsonParser *objSBJson = [[SBJsonParser alloc]init];
     NSDictionary *responseDict = [objSBJson objectWithString:respStr]; */
    resultArray = [[NSArray alloc]initWithArray:[responseDict valueForKey:@"result"]];
    NSLog(@"resultArray: %@",resultArray);
    [self.tableView reloadData];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return [resultArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    cell.textLabel.text = [[resultArray objectAtIndex:indexPath.row] valueForKey:@"name"];
    cell.detailTextLabel.text = [[resultArray objectAtIndex:indexPath.row] valueForKey:@"designation"];

    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[resultArray objectAtIndex:indexPath.row] valueForKey:@"image"]]];
cell.imageview.image = [UIImage imageWithData:imageData];

    return cell;
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [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
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/


#pragma mark - Table view delegate

// In a xib-based application, navigation from a table can be handled in -tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here, for example:
     //Create the next view controller.
    detailViewController *detailViewController1 = [[detailViewController alloc]initWithNibName:@"detailViewController" bundle:nil];

 //detailViewController *detailViewController = [[detailViewController alloc] initWithNibName:@"detailViewController" bundle:nil];

 // Pass the selected object to the new view controller.

 // Push the view controller.
 detailViewController1.nextDict = [[NSDictionary alloc]initWithDictionary:[resultArray objectAtIndex:indexPath.row]];
 [self.navigationController pushViewController:detailViewController1 animated:YES];

    // Pass the selected object to the new view controller.

    // Push the view controller.
  //  [self.navigationController pushViewController:detailViewController animated:YES];
}



@end

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    empName.text=[nextDict valueForKey:@"name"];
    deptlbl.text=[nextDict valueForKey:@"department"];
    designationLbl.text=[nextDict valueForKey:@"designation"];
    idLbl.text=[nextDict valueForKey:@"id"];
    salaryLbl.text=[nextDict valueForKey:@"salary"];
    NSString *ImageURL = [nextDict valueForKey:@"image"];
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
    image.image = [UIImage imageWithData:imageData];
}

0

বিষয়টি মনে হয় অবজেক্টের স্বতঃস্ফূর্ততা সহ। এনএসজেএসএসনারাইজেশন জেএসনোবজেক্টবিথডাটা স্পষ্টতই কিছু স্বতঃস্ফূর্ত বস্তু তৈরি করছে এবং এটি আপনার কাছে ফিরিয়ে দিচ্ছে। আপনি যদি এটি অন্য থ্রেডে নিয়ে যাওয়ার চেষ্টা করেন তবে এটি কার্যকর হবে না কারণ এটি অন্য থ্রেডে বিচ্ছিন্ন করা যায় না।

কৌশলটি হতে পারে সেই অভিধান বা অ্যারের একটি পরিবর্তনীয় অনুলিপি করে চেষ্টা করে দেখুন।

NSError *e = nil;
id jsonObject = [NSJSONSerialization 
JSONObjectWithData: data 
options: NSJSONReadingMutableContainers 
error: &e] mutableCopy];

NSArray হিসাবে একটি NSD অভিধানের চিকিত্সা খারাপ অ্যাক্সেস ব্যতিক্রম না ঘটায় তবে একটি পদ্ধতি কল করার সময় সম্ভবত এটি ক্রাশ হবে।

এছাড়াও, বিকল্পগুলি এখানে সত্যই গুরুত্বপূর্ণ নাও হতে পারে তবে এনএসজেএসএনরাইডিং মিউটেবল কনটেনারগুলি দেওয়া ভাল | এনএসজেএসআনরেডিং মিউটেবল কনটেনার্স | এনএসজেএসনআরআইডিএলফ্রেগমেন্টগুলি তবে তারা স্বতঃস্ফূর্ত অবজেক্টস হলেও এটি এই সমস্যাটিকে সমাধান করতে পারে না।


দীপক, আপনি NSJSONReadingMutableContainers দুবার তালিকাভুক্ত করেছেন। আপনি কি NSJSONReadingMutableLeaves হওয়ার জন্য বোঝাতে চেয়েছিলেন?
jk7

0

খারাপ উদাহরণ, এর মতো কিছু হওয়া উচিত {"আইডি": 1, "নাম": "নাম হিসাবে কিছু"}

সংখ্যা এবং স্ট্রিং মিশ্রিত হয়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.