1. JSONModelとは何ですか?
JSONModelは、jsonをモデルに変換するためのサードパーティのオープンソースライブラリです。サーバーにリクエストを送信した後、JSONModelを介してデータをモデル内の属性に変換することで、簡単に使用できます。
次に、JSONModelの最も基本的な使用方法
バージョンチェックAPIによって要求された最も単純なjsonデータを例として取り上げます。
送信されたバージョンはバージョン2.3であり、この時点でのjsonデータは
これは、ネットワーク要求から取得したjsonデータです。
次の手順は次のとおりです。
- Modelクラスを作成します。このクラスはJSONModelから継承されます
- 要求されたjsonデータを.hファイルの属性として宣言します。一時的に.mファイルで他のことを行う必要はありません(ネストが含まれている場合は、他のこともあります)。
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface TestModel : JSONModel
@property (nonatomic, assign) int status;
@property (nonatomic, copy) NSString* msg;
@property (nonatomic, copy) NSString* latest;
@end
NS_ASSUME_NONNULL_END
- ネットワークから要求されたデータでモデルを初期化します
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString* json = @"http://news-at.zhihu.com/api/4/version/ios/2.3.0";
json = [json stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *testUrl = [NSURL URLWithString:json];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testUrl];
NSURLSession *testSession = [NSURLSession sharedSession];
NSURLSessionDataTask *testDataTask = [testSession dataTaskWithRequest:testRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//这个TestModel就是上面说到的类
TestModel* country = [[TestModel alloc] initWithData:data error:nil];
NSLog(@"%@",country);
}];
//任务启动
[testDataTask resume];
}
渡されたJSONが有効な場合、定義するすべての属性はJSONの値に対応し、JSONModelでさえデータを期待するタイプに変換しようとします。JSONValueTransformerクラスは、次のように多くの変換を行うことをサポートできます。
NSMutableString <-> NSString
NSMutableArray <-> NSArray
NS(Mutable)Array <- JSONModelArray
NSMutableDictionary <-> NSDictionary
NSSet <-> NSArray
BOOL <-> number/string
string <-> number
string <-> url
string <-> time zone
string <-> date
number <-> date
この時点で、出力を確認できます
3、コレクション、ネストされたデータ
APIからのリクエストをまだ知っている
今回のデータは非常に複雑で、入れ子と配列がありますが、この入れ子になったモデルをどのように扱うべきでしょうか?ネストするクラスごとにクラスを作成する必要がありますが、複数のクラスファイルを作成する必要があるという意味ではなく、1つのクラスファイルで実行する必要があることを作成し、次のコードを入力するだけで済みます。
//
// TestModel.h
// JSONModel
//
// Created by young_jerry on 2020/10/12.
//
@protocol StoriesModel
@end
@protocol Top_StoriesModel
@end
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface StoriesModel : JSONModel
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *ga_prefix;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *image_hue;
@property (nonatomic, copy) NSString *id;
@end
@interface Top_StoriesModel : JSONModel
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *ga_prefix;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *image_hue;
@property (nonatomic, copy) NSString *id;
@end
@interface TestModel : JSONModel
@property (nonatomic, copy) NSString *date;
@property (nonatomic, copy) NSArray<StoriesModel>* stories;
@property (nonatomic, copy) NSArray<Top_StoriesModel>* top_stories;
//
//@property (nonatomic, assign) int status;
//@property (nonatomic, copy) NSString *msg;
//@property (nonatomic, copy) NSString *latest;
@end
NS_ASSUME_NONNULL_END
.mファイルで、クラスの実現を完了する必要があります。そうしないと、エラーが報告されます。
#import "TestModel.h"
@implementation Top_StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation TestModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
ネットワーク要求の割り当てが終了した後、top_storiesの最初のセットの値を出力します。取得が成功したことがわかります。
注意すべき4つのポイント
-
+(BOOL)propertyIsOptional:(NSString *)propertyNameは、サーバーの特定の値が返されないため(nil)、プログラムをクラッシュさせたくありません。キーワードOptionalを追加します。すべてのプロパティを追加したくない場合は、それを使用することもできます。 mファイルの書き換え方法は書き換え方式です。たとえば
、最初のAPIのmsgのバージョンが最新の場合、msgには戻り値がありません。書き込まないと、プログラムがクラッシュします。 -
私が最初にデモを書いたとき、すべては正しかったが、ネットワーク要求は失敗した
次の情報が見つかりました:
iOS9は新機能を導入しました:App Transport Security(ATS)。これは、アプリでアクセスされるネットワークがHTTPSプロトコルを使用する必要があることを要求します。
しかし現在、同社のプロジェクトはHTTPプロトコルを使用しており、データのセキュリティを確保するためにプライベート暗号化を使用しています。現在、HTTPSプロトコル送信にすぐに変更することはできません。
最終的に次の解決策を見つけました:
情報に以下を追加します
- モザイク配列の要素を取得するにはどうすればよいですか?
ドット構文が機能しないことがわかります。これはモデルのネストされたモデルであるため、直接呼び出すことはできません。
必要なネストされたモデルを宣言し、それに値を割り当てて、直接呼び出すことができます。
-
キー設定グローバルキーマッピング(すべてのモデルに適用)
は、変数の名前を変更するために.mファイルに実装されています
。
-
下線付きの名前をキャメルケースの名前属性に自動的に変換します。大文字から小文字へのような同様のメソッドがあります:mapperFromUpperCaseToLowerCase