NSCodingプロトコルを使用して設定をシリアル化します

ほとんどすべてのアプリケーションを開発する場合、遅かれ早かれ、現在のバージョンであるかアプリ内アプリケーションの設定であるかに関係なく、その設定を保存する必要があります。 この場合、開発者は何をしますか? NSUserDefaultsを介して構成データを保存し、正しいことを行います。







本当に多くの設定がある場合、それらを操作するのは不便になります。

Peers.TVアプリケーションでは、アーカイバーとNSCodingプロトコルという次のトリックを使用しました。 これにより、同じドメイン内の設定の一部を統一し、作業が少し簡単になりました。





参考のため。 Peers.TVアプリケーションは、テレビをオンラインで視聴し、テレビ番組をアーカイブするように設計されています。 今日では、さまざまな科目の30チャンネルです。 これには、先​​週のプログラム、転送時間の通知、組み込みの購入、アーカイブがあります-これらすべてには、NSCodingプロトコルにつながった独自の個別の設定が必要です。



NSCodingプロトコルの実装を、アプリケーションが第三者への望ましくないアクセスからブロックする設定の例として考えてください。

設定を伴う作業の実装は、個別のクラスであるシングルトンで実行され、設定自体はこのクラスのプロパティを介して実装されます。



次のように表示される5つの異なる設定があるとします。



@property (nonatomic, assign) BOOL isPasscodeEnabled; @property (nonatomic, assign) NSUInteger attemptCount; @property (nonatomic, assign) NSTimeInterval checkInterval; @property (nonatomic, strong) NSDate *nextCheckDate; @property (nonatomic, strong) NSString *applicationVersion;
      
      







したがって、設定ごとに、追加の1つのキーを宣言する必要があります。 プロパティの初期化と実装を行うコードもスキップされ、以下に示されます。



NSCodingプロトコルに戻ります。 このプロトコルを使用すると、オブジェクトデータのシリアル化と逆シリアル化の順序を指定できます。



このプロトコルを実装するには、2つのメソッドを実装する必要があります。



 - (void)encodeWithCoder:(NSCoder *)aCoder; - (id)initWithCoder:(NSCoder *)aDecoder;
      
      







NSKeyedArchiverクラスとNSKeyedUnarchiverクラスも必要です。これらのクラスはすべての作業を行います。 これらのクラスがキーデータのシリアル化と逆シリアル化を許可していることに注意してください。



次に、アプリケーションをブロックするための設定を組み合わせるクラスについて説明します。



インターフェース:



 @interface PassCodeSettings: NSObject<NSCoding> @property (nonatomic, assign) BOOL isPasscodeEnabled; @property (nonatomic, assign) NSUInteger attemptCount; @property (nonatomic, assign) NSTimeInterval checkInterval; @property (nonatomic, strong) NSDate *nextCheckDate; @end
      
      







実装:



 @implementation PassCodeSettings - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { _attemptCount = [aDecoder decodeIntegerForKey:@"attemptCount"]; _isPasscodeEnabled = [aDecoder decodeBoolForKey:@"isPassCodeEnabled"]; _checkInterval = [aDecoder decodeDoubleForKey:@"checkInterval"]; _nextCheckDate = [NSDate dateWithTimeIntervalSince1970:[aDecoder decodeDoubleForKey:@"nextCheckDate"]]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeBool:_isPasscodeEnabled forKey:@"isPassCodeEnabled"]; [aCoder encodeInteger:_attemptCount forKey:@"attemptCount"]; [aCoder encodeDouble:_checkInterval forKey:@"checkInterval"]; [aCoder encodeDouble:[_nextCheckDate timeIntervalSince1970] forKey:@"nextCheckDate"]; } @end
      
      







これで、アプリケーションをブロックするための設定は、NSCodingプロトコルに準拠する別のクラスに移動されます。 NSKeyedArchiver、NSKeyedUnrachiverを使用して、設定で任意のクラスの保存を実装できます。



設定の初期化と保存は次のようになります。



 - (id)init { self = [super init]; if (self) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; _applicationVersion = [defaults stringForKey:kApplicationVersion]; NSData *passCodeData = [defaults dataForKey:kPasscodeSettings]; if (passCodeData) { _passCodeSettings = [NSKeyedUnarchiver unarchiveObjectWithData:passCodeData]; } else { _passCodeSettings = [PassCodeSettings new]; } } return self; } - (void)savePasscodeSettings { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:[NSKeyedArchiver archivedDataWithRootObject:_passCodeSettings] forKey:kPasscodeSettings]; [defaults synchronize]; }
      
      







あなたの人生を楽にすることができるいくつかのトリックに言及する価値があります:

1. savePasscodeSettingsメソッドを使用して設定を手動で保存しないようにするには、KVO(キー値監視)の原則に従ってプロパティの監視を実装するか、アプリケーションライフサイクル通知を使用できます。

2. NSNotificationCenterを介して設定の変更の通知を送信することもできます。



悪名高いマイクアッシュのNSCodingプロトコルに関する興味深い記事へのリンク。



私たちが達成したこと:

-1つのドメインの設定の一部を作成し、このドメイン内のドメインデータを操作する方法をグループ化できるようになりました。

-設定での作業をわずかに促進しました。



驚いたことに、NSCodingをプロジェクトで使用してデータをシリアル化する人はほとんどいませんが、私の意見では、それは当然のことです。 もちろん、私はこれをオープンソースプロジェクトでしか判断できません。

このアプローチは特効薬ではなく、他の多くの選択肢です。 アプリケーションの構造によく適合し、開発を促進します。



それだけです 。この例のソースコードは、 ここから入手できます



NSCodingが使用されたPeers.TVアプリケーションは、AppStoreで表示できます。





Gleb Pinigin、iOS開発者



All Articles