NSUrlSession sử dụng với IOS 5 trở lên ,và bổ sung các phương thức mới cho phép dừng tải dữ liệu về, cho phép chạy ẩn vẫn load dữ liệu…Khuyên dùng Session.. API là gì các bạn hiểu sâu m
Trang 1HƯỚNG DẪN PHÂN TÍCH JSON
Json là gì ? Làm thế nào để lấy và phân tích cú pháp Json ? … trong hướng dẫn này mình sẽ giúp các bạn trả lời các câu hỏi trên
JSON (viết tắt của JavaScript Object Notation) là dựa trên văn bản để lưu trữ và trao đổi dữ liệu một cách nhẹ và dễ dàng Nó thường được sử dụng để đại diện cho dữ liệu cấu trúc và trao đổi dữ liệu trong các ứng dụng client-server, phục vụ thay thế cho XML Rất nhiều các dịch vụ chúng tôi sử dụng hàng ngày có các API JSON-based Hầu hết các ứng dụng iOS bao gồm Twitter, Facebook và Flick gửi dữ liệu đến các dịch vụ web phụ trợ của họ ở định dạng JSON
ví dụ:
favorites = (
{
artist = Brandy;
“image_large” =
“https://i.scdn.co/image/8a161e85351a20aaf4f4099cc89e1b8fb726e035”;
“image_medium” =
“https://i.scdn.co/image/3f3b3c7e4d4feabb73c885b38500d1427260ae33”;
“image_small” =
“https://i.scdn.co/image/4dcf0d5722e62cdfaf620a773f010e6b2dd15b78”;
“open_url” =
“https://open.spotify.com/track/6esN4GvN6uRe1SVVNElHDq”;
“preview_url” =
“https://p.scdn.co/mp3-preview/33add4c82a52fbaf7665b8dee3da1c73b2406775”;
“song_id” = 54dd0bc8a57fa90c00770523;
title = “I Wanna Be Down – Single Version”;
},
{
artist = “Destiny’s Child”;
Trang 2“image_large” =
“https://i.scdn.co/image/bf0f79acd50add01e88575664fe98d8d44d3123f”;
“image_medium” =
“https://i.scdn.co/image/a7aef2e8232955bb94d7c041a0fbc06b2bb8fe7f”;
“image_small” =
“https://i.scdn.co/image/fdf76dbe620b71af39d775274795c0ca2829c19f”;
“open_url” = “https://open.spotify.com/track/72oq9xR8MK5CLpI185xaVy”; “preview_url” =
“https://p.scdn.co/mp3-preview/ca5baaecfef5ce51277e105f71a8d63240b734d8”;
“song_id” = 54dd0bc8a57fa90c00770606;
title = Survivor;
},
Như bạn có thể thấy, các dữ liệu JSON là con người có thể đọc được và dễ dàng hơn với việc phân tích XML.Kể từ khi phát hành iOS 5, iOS SDK làm cho nó dễ dàng để lấy
và phân tích dữ liệu JSON…
Mình làm rõ cú pháp Json trong hướng dẫn này … cho các bạn thấy sự đơn giản và nhẹ nhàng khi sử dụng json lưu trữ!
Phần 1: Mình sẽ hướng dẫn cho các bạn phân tích và trả về json,Json mặc định ,Json setMethod ,json có tham số!
Phần 2: Mình sẽ đổ dữ liệu ra tabaleView:imageView,label…
Bắt đầu nào!
khởi tạo project mới và đặt tên: Json!
Thiết kế giao diện : vào file Main.storyboardard:
thêm 2 button đặt tên!
button1 mình sẽ sử dụng phương pháp NSUrlConnection để gọi về json!
button2 mình sẽ sử dụng phương pháp NSUrlsession để gọi về json!
Ánh xạ 2 button sang class ViewController quản lý:
Trang 31 - (IBAction)urlConnection:(id)sender {
2
3 }
1 - (IBAction)session{
2
3 }
Trang 4
NSUrlConnection sử dụng với IOS cũ, Mới vẫn dùng được, Tuy nhiên không chạy trong chế độ app chạy ẩn!, không cho phép dụng khi đang tải!
NSUrlSession sử dụng với IOS 5 trở lên ,và bổ sung các phương thức mới cho
phép dừng tải dữ liệu về, cho phép chạy ẩn vẫn load dữ liệu…Khuyên dùng Session
API là gì các bạn hiểu sâu mình sẽ không hướng dẫn ở đây, Để giúp các bạn chưa hiểu gì, đơn giản các bạn cứ hiểu là các đường dẫn truy vấn qua
Đầu tiên mình sẽ hướng dẫn các bạn sử dụng NSUrlConnnection!
Trang 5Trong url urlConnnection ta vừa ánh xạ sang, Thêm đoạn mã sau!
1 - (IBAction)urlConnection:(id)sender {
2 NSString *strUrl=@"https://ionic-songhop.herokuapp.com/login";
3 NSURL *url=[NSURL URLWithString:strUrl];
4 NSURLRequest *request= [NSURLRequest requestWithURL:url];
5 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError) {
6 if (connectionError==nil) {
7
8
9 NSLog(@"%@",data);
10 }else{
11 NSLog(@"%@",connectionError);
12 }
13 }];
14 NSLog(@"requesting");
15 }
Đầu tiên lấy một chuỗi đường dẫn đến nơi cung cấp API free!
Chuyển đổi thành url-> chuyển đổi thành request
NSURLConnection có phương thức chung là sendAsychronousRequest để lấy dữ liệu
về dạng data
Tham số đầu tiên là truyền vào request , Đăng ký đa
luồng queue:[NSOperationQueuemainQueue], Mainqueue luồng chính chạy app của chúng ta
đăng ký luồng phụ chuyên load dữ liệu từ trên mạng về Nếu ta không đăng ký đa luồng thì khi ứng dụng chạy đến đoạn tải dữ liệu sẽ chờ load, mất thời gian có thể app sẽ bị dừng nếu timeout Đăng ký chạy đa luồng giúp cho việc load dữ liệu chạy luồng riêng khi nó hoàn thành trả về block cho mainqueue update dữ liệu
block trả về có data or error :
Kiểm tra nếu có lỗi thông báo error nếu không trả về data
Chạy thử các bạn sẽ nhận đượcđược :
1 2016-05-2310:15:34.314 Json[829:14677] requesting
2
3 2016-05-2310:15:34.913 Json[829:14677] <3c68313e 4e6f7420 466f756e 643c2f68 313e0a3c 68323e75 6e646566 696e6564 3c2f6832 3e0a3c70 72653e75 6e646566 696e6564 3c2f7072 653e0a>
Trang 6Như vậy chúng ta đã có data trả về!
Tiếp theo chúng ta sử dụng NSURLSession:
Ở đây mình sẽ viết một hàm có truyền tham số, và có truyền đường dẫn cung cấp API tham số là para vs đường dẫn là urlApi
ban đầu đơn giản mình sẽ chưa sử dụng tham số khi truyền, và chưa xét phương thức gửi dữ liệu!
Mình làm tương tự như connection,lấy url chuyển thành request, Tuy nhiên session chạy bằng các task mỗi task là một luồng riêng trả về block riêng chứ không sử dụng queue để sắp xếp luồng
và sử dụng phương thức sharedSession để gọi về dataTaskWithRequest: tham số đầu tiên truyền vào request mà chúng ta vừa tạo, ngay khi có dữ liệu hoàn thành trả về block -> trả về cho task
task chúng ta cho phép tải hoặc dừng!Để đơn giản mình chỉ log ra data
1 -void)urlSession:(NSDictionary *)para urlApi:(NSString*)urlApi{
2 NSURL *url=[NSURL URLWithString:urlApi];
3 NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url];
4
5
6 NSURLSessionDataTask *task=[[NSURLSession sharedSession]dataTaskWithRequest:request
completionHandler:^(NSData * data, NSURLResponse *response, NSError *error) {
7 NSError *errorData;
8 if (error==nil) {
9 NSLog(@"%@",data);
10 }else{
11 NSLog(@"%@",error);
12 }
13 }];
14 [task resume];
15 }
Chúng ta truyền tham số và đường dẫn khi nhấn vào button session!
1 - (IBAction)session{
2 NSString *strUrl=@"https://ionic-songhop.herokuapp.com/login";
3 NSDictionary *key=@{@"username":@"hiep"};
4 [self urlSession:key urlApi:strUrl];
5 }
NSLog ra kết quả:
Trang 71 2016-05-2310:15:34.913 Json[829:14677] <3c68313e 4e6f7420 466f756e 643c2f68 313e0a3c 68323e75 6e646566 696e6564 3c2f6832 3e0a3c70 72653e75 6e646566 696e6564 3c2f7072 653e0a>
tất cả 2 phương pháp trên chúng ta mới trả về data chưa chuyển chúng sang Json!
Để đơn giản mình chỉ làm việc với NSURLSession trả về Json còn connection tương
tự ở đoạn chuyển đổi sang Json
chúng ta thay đổi đoạn mã trên chúng ta không NSLog ra data
khai báo một NSError *errorData để trả về khi nó không phải là Json.do API này chúng
ta biết nó là một kiểu dictionary nên ta khai báo conten
[NSJSONSerialization JSONObjectWithData:dataoptions:NSJSONReadingAllowFragm ents error:&errorData]; truyền vào data cần chuyển đổi thành json, kiểu căn lề,truyền vào error nếu có lỗi không phải json.Kiểm tra nếu không có lỗi xuất ra json nếu có lỗi xuất ra lỗi và chuyển bó sang kiểu UTF8 để đọc lỗi
1 -void)urlSession:(NSDictionary *)para urlApi:(NSString*)urlApi{
2 NSURL *url=[NSURL URLWithString:urlApi];
3 NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url];
4 NSURLSessionDataTask *task=[[NSURLSession sharedSession]dataTaskWithRequest:request
completionHandler:^(NSData * data, NSURLResponse *response, NSError *error) {
5 NSError *errorData;
6 if (error==nil) {// kiểm tra nếu có data
7 NSDictionary *conten=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&errorData];
8 if (errorData==nil) {
9 NSLog(@"%@",conten);
10 }else{
11 NSString *contenError=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
12 NSLog(@"%@",contenError);
13 }
14 }
15 }];
16 }
Biên dịch và chạy thử ta được kết quả như sau:
1 2016-05-2310:50:30.650 Json[973:39016] <h1>Not Found</h1>
2 <h2>undefined</h2>
3 <pre>undefined</pre>
Xuất ra lỗi không trả về Json do dữ liệu không phải kiểu Json Hàm mặc định của phương thức trả về data là get.Lỗi này do đường dẫn trả về API không phải phương thức get mà là phương thức thức post
Trang 8chúng ta thêm câu lệnh xét phương thức trả về:
1 [request setHTTPMethod:@"POST"];
chúng ta thêm ngay sau đoạn trả về request!
1 -void)urlSession:(NSDictionary *)para urlApi:(NSString*)urlApi{
2 NSURL *url=[NSURL URLWithString:urlApi];
3 NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url];
4 [request setHTTPMethod:@"POST"];
5 NSURLSessionDataTask *task=[[NSURLSession sharedSession]dataTaskWithRequest:request
completionHandler:^(NSData * data, NSURLResponse *response, NSError *error) {
6 NSError *errorData;
7 if (error==nil) {// kiểm tra nếu có data
8 NSDictionary *conten=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&errorData];
9 if (errorData==nil) {
10 NSLog(@"%@",conten);
11 }else{
12 NSString *contenError=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
13 NSLog(@"%@",contenError);
14 }
15 }
16 }];
17 }
chạy và biên dịch chúng ta sẽ NSLog ra đoạn mã json sau:
1 2016-05-2310:57:09.299 Json[990:40954] {
2 favorites = (
3 {
4 artist = "Mr Big";
5 "image_large" = "https://i.scdn.co/image/a16e2885c64a9019f308bd21dc717e14819ea93b";
6 "image_medium" = "https://i.scdn.co/image/737ee10e67a9829b04fba3dbd5a7df49442cb8e3";
7 "image_small" = "https://i.scdn.co/image/71675961c21c2a48c87e154e178fa1b21e73e8d4";
8 "open_url" = "https://open.spotify.com/track/4E7D9GuRmqsz2rizLOiQom";
9 "preview_url" = "https://p.scdn.co/mp3-preview/4a2b0fd83318acff32e60c58deb0079ceeffce3d";
10 "song_id" = 54dd0bc8a57fa90c0077065b;
11 title = "To Be With You";
12 },
13 {
14 artist = "Gwen Stefani";
15 "image_large" = "https://i.scdn.co/image/021fe86098015008463597fbd1b40ea0aca3bb14";
16 "image_medium" = "https://i.scdn.co/image/78d2d152c50e139dd29bd8e02f892bfc3af7fc6b";
17 "image_small" = "https://i.scdn.co/image/49ddb3c72d514b9764cd0e90eee2fe218cb9ae3b";
18 "open_url" = "https://open.spotify.com/track/4t0DvmrYqArFKKqCtdaXfG";
19 "preview_url" = "https://p.scdn.co/mp3-preview/dd120963776598cfe865fd8301e1987d4e72c49c";
Trang 920 "song_id" = 54dd0bc8a57fa90c0077054a;
21 title = "Rich Girl";
22 }
23 );
24 "session_id" = 571a3372af073411005963c7;
25 username = jay;
26 }
như thế chúng ta đã đọc được Json Tuy nhiên sử dụng tham số para như thế nào ? Tham số truyền là gì ? ví dụ trên CSDL có lưu thông tin của từng người dùng họ yêu thích những bài hát gì, truyện gì … khi đó từng người dùng là para tham số Để truy vấn dữ liệu tưng ngừoi dùng chúng ta thêm đoạn mã sau!!!
1 if (para!=nil) {
2 NSMutableArray *endcodeParaCompos =[[NSMutableArray alloc]init];
3 for (NSString *key in para) {
4 [endcodeParaCompos addObject:[NSString stringWithFormat:@"%@=%@",key,para[key]]];
5 }
6 NSData *encodeParas=[[endcodeParaCompos componentsJoinedByString:@"&"]
dataUsingEncoding:NSUTF8StringEncoding];
7 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
8 [request setValue:[NSString stringWithFormat:@"%d",(int)encodeParas.length] forHTTPHeaderField:@"Content-Length"];
9 request.HTTPBody=encodeParas;
10 }
Kiểm tra nếu có para , thì ta truyền tham số đây là đoạn mã truyền tham số các quy định tuân theo, Khởi tạo một mảng để lưu key value theo định dạng %@=%@
chuyển đổi para sang NSData application/x-www-form-urlencoded kiểu hiển thị phổ biến cuối cung gửi para đi
đoạn mã trên thêm vào sau khi xet method, đầy đủ sẽ trông như sau:
1 -void)urlSession:(NSDictionary *)para urlApi:(NSString*)urlApi{
2 NSURL *url=[NSURL URLWithString:urlApi];
3 NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url];
4 [request setHTTPMethod:@"POST"];
5 if (para!=nil) {
6 NSMutableArray *endcodeParaCompos =[[NSMutableArray alloc]init];
7 for (NSString *key in para) {
8 [endcodeParaCompos addObject:[NSString stringWithFormat:@"%@=%@",key,para[key]]];
9 }
10 NSData *encodeParas=[[endcodeParaCompos componentsJoinedByString:@"&"]
dataUsingEncoding:NSUTF8StringEncoding];
11 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
Trang 1012 [request setValue:[NSString stringWithFormat:@"%d",(int)encodeParas.length] forHTTPHeaderField:@"Content-Length"];
13 request.HTTPBody=encodeParas;
14 }
15
16 NSURLSessionDataTask *task=[[NSURLSession sharedSession]dataTaskWithRequest:request
completionHandler:^(NSData * data, NSURLResponse *response, NSError *error) {
17 NSError *errorData;
18 if (error==nil) {
19 NSDictionary *conten=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&errorData];
20 if (errorData==nil) {
21 NSLog(@"%@",conten);
22 }else{
23 NSString *contenError=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
24 NSLog(@"%@",contenError);
25 }
26 }
27 }];
28 [task resume];
29 }
ở đây tôi truyền tham số là hiep:
1 - (IBAction)session{
2 NSString *strUrl=@"https://ionic-songhop.herokuapp.com/login";
3 NSDictionary *key=@{@"username":@"hiep"};
4 [self urlSession:key urlApi:strUrl];
5 }
Biên dịch và chạy ta NSLog ra được kết quả:
1 2016-05-2311:13:06.052 Json[1038:45980] {
2 favorites = (
3 {
4 artist = Brandy;
5 "image_large" = "https://i.scdn.co/image/8a161e85351a20aaf4f4099cc89e1b8fb726e035";
6 "image_medium" = "https://i.scdn.co/image/3f3b3c7e4d4feabb73c885b38500d1427260ae33";
7 "image_small" = "https://i.scdn.co/image/4dcf0d5722e62cdfaf620a773f010e6b2dd15b78";
8 "open_url" = "https://open.spotify.com/track/6esN4GvN6uRe1SVVNElHDq";
9 "preview_url" = "https://p.scdn.co/mp3-preview/33add4c82a52fbaf7665b8dee3da1c73b2406775";
10 "song_id" = 54dd0bc8a57fa90c00770523;
11 title = "I Wanna Be Down - Single Version";
12 },
13 {
14 artist = "Destiny's Child";
15 "image_large" = "https://i.scdn.co/image/bf0f79acd50add01e88575664fe98d8d44d3123f";
16 "image_medium" = "https://i.scdn.co/image/a7aef2e8232955bb94d7c041a0fbc06b2bb8fe7f";
17 "image_small" = "https://i.scdn.co/image/fdf76dbe620b71af39d775274795c0ca2829c19f";
18 "open_url" = "https://open.spotify.com/track/72oq9xR8MK5CLpI185xaVy";