Saya pikir saya tahu apa yang menyebabkan kesalahan ini, tapi aku bisa't tampak untuk mencari tahu apa yang saya lakukan salah.
Berikut adalah pesan kesalahan penuh saya mendapatkan:
Upaya untuk menetapkan non-properti-daftar objek ( "<BC_Person: 0x8f3c140>" ) sebagai NSUserDefaults nilai untuk kunci personDataArray
Aku punya Seseorang
kelas yang saya pikir adalah yang sesuai dengan majic jungle software
protokol, di mana saya memiliki kedua metode ini di kelas orang:
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:self.personsName forKey:@"BCPersonsName"];
[coder encodeObject:self.personsBills forKey:@"BCPersonsBillsArray"];
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
self.personsName = [coder decodeObjectForKey:@"BCPersonsName"];
self.personsBills = [coder decodeObjectForKey:@"BCPersonsBillsArray"];
}
return self;
}
Di beberapa titik dalam aplikasi, NSString
di BC_PersonClass
diatur, dan saya memiliki DataSave
kelas yang saya pikir adalah penanganan pengkodean sifat saya BC_PersonClass
.
Berikut adalah kode yang saya gunakan dari DataSave
kelas:
- (void)savePersonArrayData:(BC_Person *)personObject
{
// NSLog(@"name of the person %@", personObject.personsName);
[mutableDataArray addObject:personObject];
// set the temp array to the mutableData array
tempMuteArray = [NSMutableArray arrayWithArray:mutableDataArray];
// save the person object as nsData
NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];
// first add the person object to the mutable array
[tempMuteArray addObject:personEncodedObject];
// NSLog(@"Objects in the array %lu", (unsigned long)mutableDataArray.count);
// now we set that data array to the mutable array for saving
dataArray = [[NSArray alloc] initWithArray:mutableDataArray];
//dataArray = [NSArray arrayWithArray:mutableDataArray];
// save the object to NS User Defaults
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:dataArray forKey:@"personDataArray"];
[userData synchronize];
}
Saya harap ini cukup kode untuk memberikan gambaran o apa yang saya coba lakukan. Sekali lagi saya tahu masalah saya berbohong dengan cara saya pengkodean properti saya di saya BC_Person kelas, aku hanya bisa't tampaknya untuk mencari tahu apa meskipun aku'm melakukan hal yang salah.
Terima kasih atas bantuan!
Kode anda diposting mencoba untuk menyimpan sebuah array dari objek kustom untuk NSUserDefaults
. Anda dapat't melakukan itu. Menerapkan majic jungle software
metode doesn't membantu. Anda hanya dapat menyimpan hal-hal seperti NSArray
, NSDictionary
, NSString
, NSData
, NSNumber
, dan NSDate
di NSUserDefaults
.
Anda perlu mengkonversi objek ke NSData
(seperti anda memiliki beberapa kode) dan toko yang NSData
di NSUserDefaults
. Anda bahkan dapat menyimpan sebuah NSArray
dari NSData
jika anda perlu untuk.
Ketika anda membaca kembali array yang anda butuhkan untuk membuka arsip yang NSData
untuk mendapatkan anda kembali BC_Person
benda-benda.
Mungkin anda ingin ini:
- (void)savePersonArrayData:(BC_Person *)personObject {
[mutableDataArray addObject:personObject];
NSMutableArray *archiveArray = [NSMutableArray arrayWithCapacity:mutableDataArray.count];
for (BC_Person *personObject in mutableDataArray) {
NSData *personEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:personObject];
[archiveArray addObject:personEncodedObject];
}
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:archiveArray forKey:@"personDataArray"];
}
Tampaknya agak boros untuk saya untuk menjalankan melalui array dan encode benda-benda ke NSData diri sendiri. Anda error BC_Person adalah non-properti-daftar objek
memberitahu anda bahwa kerangka doesn't tahu bagaimana untuk membuat anda orang yang objek.
Jadi semua yang diperlukan adalah untuk memastikan bahwa anda orang yang objek sesuai dengan majic jungle software, maka anda hanya dapat mengkonversi array dari objek kustom ke NSData dan toko yang ke default. Heres bermain anak:
Edit: Menulis untuk NSUserDefaults
rusak pada Xcode 7 jadi taman bermain akan arsip untuk data dan kembali dan mencetak output. Yang UserDefaults langkah ini termasuk dalam kasus yang tetap pada suatu titik kemudian
//: Playground - noun: a place where people can play
import Foundation
class Person: NSObject, NSCoding {
let surname: String
let firstname: String
required init(firstname:String, surname:String) {
self.firstname = firstname
self.surname = surname
super.init()
}
//MARK: - NSCoding -
required init(coder aDecoder: NSCoder) {
surname = aDecoder.decodeObjectForKey("surname") as! String
firstname = aDecoder.decodeObjectForKey("firstname") as! String
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(firstname, forKey: "firstname")
aCoder.encodeObject(surname, forKey: "surname")
}
}
//: ### Now lets define a function to convert our array to NSData
func archivePeople(people:[Person]) -> NSData {
let archivedObject = NSKeyedArchiver.archivedDataWithRootObject(people as NSArray)
return archivedObject
}
//: ### Create some people
let people = [Person(firstname: "johnny", surname:"appleseed"),Person(firstname: "peter", surname: "mill")]
//: ### Archive our people to NSData
let peopleData = archivePeople(people)
if let unarchivedPeople = NSKeyedUnarchiver.unarchiveObjectWithData(peopleData) as? [Person] {
for person in unarchivedPeople {
print("\(person.firstname), you have been unarchived")
}
} else {
print("Failed to unarchive people")
}
//: ### Lets try use NSUserDefaults
let UserDefaultsPeopleKey = "peoplekey"
func savePeople(people:[Person]) {
let archivedObject = archivePeople(people)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(archivedObject, forKey: UserDefaultsPeopleKey)
defaults.synchronize()
}
func retrievePeople() -> [Person]? {
if let unarchivedObject = NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultsPeopleKey) as? NSData {
return NSKeyedUnarchiver.unarchiveObjectWithData(unarchivedObject) as? [Person]
}
return nil
}
if let retrievedPeople = retrievePeople() {
for person in retrievedPeople {
print("\(person.firstname), you have been unarchived")
}
} else {
print("Writing to UserDefaults is still broken in playgrounds")
}
Dan Voila, anda telah disimpan dalam sebuah array dari objek kustom ke NSUserDefaults
Untuk menyimpan:
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:yourObject];
[currentDefaults setObject:data forKey:@"yourKeyName"];
Untuk Mendapatkan:
NSData *data = [currentDefaults objectForKey:@"yourKeyName"];
yourObjectType * token = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Untuk Menghapus
[currentDefaults removeObjectForKey:@"yourKeyName"];
class ArchiveUtil {
private static let PeopleKey = "PeopleKey"
private static func archivePeople(people : [Human]) -> NSData {
return NSKeyedArchiver.archivedData(withRootObject: people as NSArray) as NSData
}
static func loadPeople() -> [Human]? {
if let unarchivedObject = UserDefaults.standard.object(forKey: PeopleKey) as? Data {
return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [Human]
}
return nil
}
static func savePeople(people : [Human]?) {
let archivedObject = archivePeople(people: people!)
UserDefaults.standard.set(archivedObject, forKey: PeopleKey)
UserDefaults.standard.synchronize()
}
}
class Human: NSObject, NSCoding {
var name:String?
var age:Int?
required init(n:String, a:Int) {
name = n
age = a
}
required init(coder aDecoder: NSCoder) {
name = aDecoder.decodeObject(forKey: "name") as? String
age = aDecoder.decodeInteger(forKey: "age")
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(age, forKey: "age")
}
}
var people = [Human]()
people.append(Human(n: "Sazzad", a: 21))
people.append(Human(n: "Hissain", a: 22))
people.append(Human(n: "Khan", a: 23))
ArchiveUtil.savePeople(people: people)
let others = ArchiveUtil.loadPeople()
for human in others! {
print("name = \(human.name!), age = \(human.age!)")
}
mencoba kode ini
anda tidak dapat menyimpan mapper di NSUserDefault, anda hanya dapat menyimpan NSData, NSString, NSNumber, NSDate, NSArray, atau NSDictionary.
let myData = NSKeyedArchiver.archivedData(withRootObject: myJson)
UserDefaults.standard.set(myData, forKey: "userJson")
let recovedUserJsonData = UserDefaults.standard.object(forKey: "userJson")
let recovedUserJson = NSKeyedUnarchiver.unarchiveObject(with: recovedUserJsonData)
Pertama, rmaddy's jawaban (atas) kanan: menerapkan majic jungle software
doesn't membantu. Namun, anda perlu menerapkan majic jungle software
menggunakan NSKeyedArchiver
dan semua itu, jadi itu's hanya satu langkah lagi... konversi melalui NSData
.
Contoh metode
- (NSUserDefaults *) defaults {
return [NSUserDefaults standardUserDefaults];
}
- (void) persistObj:(id)value forKey:(NSString *)key {
[self.defaults setObject:value forKey:key];
[self.defaults synchronize];
}
- (void) persistObjAsData:(id)encodableObject forKey:(NSString *)key {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:encodableObject];
[self persistObj:data forKey:key];
}
- (id) objectFromDataWithKey:(NSString*)key {
NSData *data = [self.defaults objectForKey:key];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
Jadi anda bisa membungkus majic jungle software
benda-benda di sebuah NSArray
atau NSDictionary
atau apapun...
Aku punya masalah ini mencoba menyelamatkan sebuah kamus untuk NSUserDefaults
. Ternyata itu tidak't menghemat karena mengandung NSNull
nilai-nilai. Jadi aku hanya disalin kamus menjadi bisa berubah kamus dihapus nulls kemudian disimpan ke NSUserDefaults
NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithDictionary:dictionary_trying_to_save];
[dictionary removeObjectForKey:@"NullKey"];
[[NSUserDefaults standardUserDefaults] setObject:dictionary forKey:@"key"];
Dalam hal ini aku tahu tombol yang mungkin NSNull
nilai-nilai.
default objek harus daftar properti—yang, contoh (atau untuk koleksi, kombinasi dari kasus): NSData, NSString, NSNumber, NSDate, NSArray, atau NSDictionary.
Jika anda ingin menyimpan jenis lain dari objek, anda biasanya harus arsip itu untuk membuat sebuah instance dari NSData. Untuk lebih jelasnya, lihat Preferensi dan Pengaturan Panduan Pemrograman.
Swift 5: Codable protokol yang dapat digunakan sebagai pengganti NSKeyedArchiever.
struct User: Codable {
let id: String
let mail: String
let fullName: String
}
The I struct adalah custom bungkus sekitar UserDefaults benda standar.
struct Pref {
static let keyUser = "Pref.User"
static var user: User? {
get {
if let data = UserDefaults.standard.object(forKey: keyUser) as? Data {
do {
return try JSONDecoder().decode(User.self, from: data)
} catch {
print("Error while decoding user data")
}
}
return nil
}
set {
if let newValue = newValue {
do {
let data = try JSONEncoder().encode(newValue)
UserDefaults.standard.set(data, forKey: keyUser)
} catch {
print("Error while encoding user data")
}
} else {
UserDefaults.standard.removeObject(forKey: keyUser)
}
}
}
}
Sehingga anda dapat menggunakan cara ini:
Pref.user?.name = "John"
if let user = Pref.user {...
Swift 5 cara yang Sangat Mudah
//MARK:- First you need to encoded your arr or what ever object you want to save in UserDefaults
//in my case i want to save Picture (NMutableArray) in the User Defaults in
//in this array some objects are UIImage & Strings
//first i have to encoded the NMutableArray
let encodedData = NSKeyedArchiver.archivedData(withRootObject: yourArrayName)
//MARK:- Array save in UserDefaults
defaults.set(encodedData, forKey: "YourKeyName")
//MARK:- When you want to retreive data from UserDefaults
let decoded = defaults.object(forKey: "YourKeyName") as! Data
yourArrayName = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! NSMutableArray
//MARK: Enjoy this arrry "yourArrayName"