Unarchive Array with NSKeyedUnarchiver unarchivedObject(ofClass:from:)
Since upgrading to Swift 4.2 I've found that many of the NSKeyedUnarchiver and NSKeyedArchiver methods have been deprecated and we must now use the type method static func unarchivedObject<DecodedObjectType>(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType? to unarchive data.
I have managed to successfully archive an Array of my bespoke class WidgetData, which is an NSObject subclass:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> NSData
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: widgetDataArray as Array, requiringSecureCoding: false) as NSData
else fatalError("Can't encode data")
return data
The problem comes when I try to unarchive this data:
static func loadWidgetDataArray() -> [WidgetData]?
if isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA)
if let unarchivedObject = UserDefaults.standard.object(forKey: USER_DEFAULTS_KEY_WIDGET_DATA) as? Data
//THIS FUNCTION HAS NOW BEEN DEPRECATED:
//return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [WidgetData]
guard let nsArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: unarchivedObject as Data) else
fatalError("loadWidgetDataArray - Can't encode data")
guard let array = nsArray as? Array<WidgetData> else
fatalError("loadWidgetDataArray - Can't get Array")
return array
return nil
But this fails, as using Array.self instead of NSArray.self is disallowed. What am I doing wrong and how can I fix this to unarchive my Array?
ios swift nskeyedunarchiver ios12
|
show 1 more comment
Since upgrading to Swift 4.2 I've found that many of the NSKeyedUnarchiver and NSKeyedArchiver methods have been deprecated and we must now use the type method static func unarchivedObject<DecodedObjectType>(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType? to unarchive data.
I have managed to successfully archive an Array of my bespoke class WidgetData, which is an NSObject subclass:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> NSData
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: widgetDataArray as Array, requiringSecureCoding: false) as NSData
else fatalError("Can't encode data")
return data
The problem comes when I try to unarchive this data:
static func loadWidgetDataArray() -> [WidgetData]?
if isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA)
if let unarchivedObject = UserDefaults.standard.object(forKey: USER_DEFAULTS_KEY_WIDGET_DATA) as? Data
//THIS FUNCTION HAS NOW BEEN DEPRECATED:
//return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [WidgetData]
guard let nsArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: unarchivedObject as Data) else
fatalError("loadWidgetDataArray - Can't encode data")
guard let array = nsArray as? Array<WidgetData> else
fatalError("loadWidgetDataArray - Can't get Array")
return array
return nil
But this fails, as using Array.self instead of NSArray.self is disallowed. What am I doing wrong and how can I fix this to unarchive my Array?
ios swift nskeyedunarchiver ios12
Check this for a more swifty solution stackoverflow.com/a/51460950/5820010
– Sh_Khan
Jul 23 '18 at 21:53
What "fails"? What output do you get? You aren't usingArray.selfanywhere.
– Paulw11
Jul 23 '18 at 22:34
When changed to Array.self instead of NSArray.self, the pre-compiler complains: Incorrect argument label in call (have 'ofClass:from:', expected 'ofClasses:from:') Replace 'ofClass' with 'ofClasses'. Which implies Array.self can't be used. When I use NSArray.self it compiles without issue & runs. But gets caught by the fatal error as the resulting 'nsArray' is nil.
– Geoff H
Jul 23 '18 at 22:38
So, what happens when you useNSKeyedUnarchiver.unarchivedObject(ofClasses: [Array<WidgetData>.self], from: unarchivedObject as Data)? Also, instead of usingtry?usedo/try/catchso that you can print the actual error that occurred.
– Paulw11
Jul 23 '18 at 22:45
It results in the following complaint: Cannot convert value of type 'Array<WidgetData>.Type' to expected element type 'AnyObject.Type' Insert ' as! AnyObject.Type'
– Geoff H
Jul 23 '18 at 22:59
|
show 1 more comment
Since upgrading to Swift 4.2 I've found that many of the NSKeyedUnarchiver and NSKeyedArchiver methods have been deprecated and we must now use the type method static func unarchivedObject<DecodedObjectType>(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType? to unarchive data.
I have managed to successfully archive an Array of my bespoke class WidgetData, which is an NSObject subclass:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> NSData
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: widgetDataArray as Array, requiringSecureCoding: false) as NSData
else fatalError("Can't encode data")
return data
The problem comes when I try to unarchive this data:
static func loadWidgetDataArray() -> [WidgetData]?
if isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA)
if let unarchivedObject = UserDefaults.standard.object(forKey: USER_DEFAULTS_KEY_WIDGET_DATA) as? Data
//THIS FUNCTION HAS NOW BEEN DEPRECATED:
//return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [WidgetData]
guard let nsArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: unarchivedObject as Data) else
fatalError("loadWidgetDataArray - Can't encode data")
guard let array = nsArray as? Array<WidgetData> else
fatalError("loadWidgetDataArray - Can't get Array")
return array
return nil
But this fails, as using Array.self instead of NSArray.self is disallowed. What am I doing wrong and how can I fix this to unarchive my Array?
ios swift nskeyedunarchiver ios12
Since upgrading to Swift 4.2 I've found that many of the NSKeyedUnarchiver and NSKeyedArchiver methods have been deprecated and we must now use the type method static func unarchivedObject<DecodedObjectType>(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType? to unarchive data.
I have managed to successfully archive an Array of my bespoke class WidgetData, which is an NSObject subclass:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> NSData
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: widgetDataArray as Array, requiringSecureCoding: false) as NSData
else fatalError("Can't encode data")
return data
The problem comes when I try to unarchive this data:
static func loadWidgetDataArray() -> [WidgetData]?
if isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA)
if let unarchivedObject = UserDefaults.standard.object(forKey: USER_DEFAULTS_KEY_WIDGET_DATA) as? Data
//THIS FUNCTION HAS NOW BEEN DEPRECATED:
//return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [WidgetData]
guard let nsArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: unarchivedObject as Data) else
fatalError("loadWidgetDataArray - Can't encode data")
guard let array = nsArray as? Array<WidgetData> else
fatalError("loadWidgetDataArray - Can't get Array")
return array
return nil
But this fails, as using Array.self instead of NSArray.self is disallowed. What am I doing wrong and how can I fix this to unarchive my Array?
ios swift nskeyedunarchiver ios12
ios swift nskeyedunarchiver ios12
edited Aug 1 '18 at 20:06
Ashley Mills
29k989117
29k989117
asked Jul 23 '18 at 21:47
Geoff HGeoff H
1,2611630
1,2611630
Check this for a more swifty solution stackoverflow.com/a/51460950/5820010
– Sh_Khan
Jul 23 '18 at 21:53
What "fails"? What output do you get? You aren't usingArray.selfanywhere.
– Paulw11
Jul 23 '18 at 22:34
When changed to Array.self instead of NSArray.self, the pre-compiler complains: Incorrect argument label in call (have 'ofClass:from:', expected 'ofClasses:from:') Replace 'ofClass' with 'ofClasses'. Which implies Array.self can't be used. When I use NSArray.self it compiles without issue & runs. But gets caught by the fatal error as the resulting 'nsArray' is nil.
– Geoff H
Jul 23 '18 at 22:38
So, what happens when you useNSKeyedUnarchiver.unarchivedObject(ofClasses: [Array<WidgetData>.self], from: unarchivedObject as Data)? Also, instead of usingtry?usedo/try/catchso that you can print the actual error that occurred.
– Paulw11
Jul 23 '18 at 22:45
It results in the following complaint: Cannot convert value of type 'Array<WidgetData>.Type' to expected element type 'AnyObject.Type' Insert ' as! AnyObject.Type'
– Geoff H
Jul 23 '18 at 22:59
|
show 1 more comment
Check this for a more swifty solution stackoverflow.com/a/51460950/5820010
– Sh_Khan
Jul 23 '18 at 21:53
What "fails"? What output do you get? You aren't usingArray.selfanywhere.
– Paulw11
Jul 23 '18 at 22:34
When changed to Array.self instead of NSArray.self, the pre-compiler complains: Incorrect argument label in call (have 'ofClass:from:', expected 'ofClasses:from:') Replace 'ofClass' with 'ofClasses'. Which implies Array.self can't be used. When I use NSArray.self it compiles without issue & runs. But gets caught by the fatal error as the resulting 'nsArray' is nil.
– Geoff H
Jul 23 '18 at 22:38
So, what happens when you useNSKeyedUnarchiver.unarchivedObject(ofClasses: [Array<WidgetData>.self], from: unarchivedObject as Data)? Also, instead of usingtry?usedo/try/catchso that you can print the actual error that occurred.
– Paulw11
Jul 23 '18 at 22:45
It results in the following complaint: Cannot convert value of type 'Array<WidgetData>.Type' to expected element type 'AnyObject.Type' Insert ' as! AnyObject.Type'
– Geoff H
Jul 23 '18 at 22:59
Check this for a more swifty solution stackoverflow.com/a/51460950/5820010
– Sh_Khan
Jul 23 '18 at 21:53
Check this for a more swifty solution stackoverflow.com/a/51460950/5820010
– Sh_Khan
Jul 23 '18 at 21:53
What "fails"? What output do you get? You aren't using
Array.self anywhere.– Paulw11
Jul 23 '18 at 22:34
What "fails"? What output do you get? You aren't using
Array.self anywhere.– Paulw11
Jul 23 '18 at 22:34
When changed to Array.self instead of NSArray.self, the pre-compiler complains: Incorrect argument label in call (have 'ofClass:from:', expected 'ofClasses:from:') Replace 'ofClass' with 'ofClasses'. Which implies Array.self can't be used. When I use NSArray.self it compiles without issue & runs. But gets caught by the fatal error as the resulting 'nsArray' is nil.
– Geoff H
Jul 23 '18 at 22:38
When changed to Array.self instead of NSArray.self, the pre-compiler complains: Incorrect argument label in call (have 'ofClass:from:', expected 'ofClasses:from:') Replace 'ofClass' with 'ofClasses'. Which implies Array.self can't be used. When I use NSArray.self it compiles without issue & runs. But gets caught by the fatal error as the resulting 'nsArray' is nil.
– Geoff H
Jul 23 '18 at 22:38
So, what happens when you use
NSKeyedUnarchiver.unarchivedObject(ofClasses: [Array<WidgetData>.self], from: unarchivedObject as Data)? Also, instead of using try? use do/try/catch so that you can print the actual error that occurred.– Paulw11
Jul 23 '18 at 22:45
So, what happens when you use
NSKeyedUnarchiver.unarchivedObject(ofClasses: [Array<WidgetData>.self], from: unarchivedObject as Data)? Also, instead of using try? use do/try/catch so that you can print the actual error that occurred.– Paulw11
Jul 23 '18 at 22:45
It results in the following complaint: Cannot convert value of type 'Array<WidgetData>.Type' to expected element type 'AnyObject.Type' Insert ' as! AnyObject.Type'
– Geoff H
Jul 23 '18 at 22:59
It results in the following complaint: Cannot convert value of type 'Array<WidgetData>.Type' to expected element type 'AnyObject.Type' Insert ' as! AnyObject.Type'
– Geoff H
Jul 23 '18 at 22:59
|
show 1 more comment
4 Answers
4
active
oldest
votes
You can use unarchiveTopLevelObjectWithData(_:) to unarchive the data archived by archivedData(withRootObject:requiringSecureCoding:). (I believe this is not deprecated yet.)
But before showing some code, you should better:
Avoid using
NSData, useDatainsteadAvoid using
try?which disposes error info useful for debuggingRemove all unneeded casts
Try this:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data
do
let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)
return data
catch
fatalError("Can't encode data: (error)")
static func loadWidgetDataArray() -> [WidgetData]?
guard
isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
else
return nil
do
guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else
fatalError("loadWidgetDataArray - Can't get Array")
return array
catch
fatalError("loadWidgetDataArray - Can't encode data: (error)")
But if you are making a new app, you should better consider using Codable.
That hit the nail on the head. Thank you so much. Yes, I'm making a new app. If you could shed a little light on Codable.. You got my attention. Where should I start with it & why is it important.
– Geoff H
Jul 23 '18 at 23:03
2
@GeoffH, it's native Swift way of serializing (archiving). (For example, it works with[WidgetData].self, you have no need to care aboutNSArrayor some otherNS-things.) Better start with searching "swift codable" and you can find many good articles.
– OOPer
Jul 23 '18 at 23:08
Will do. Thank you so much for your help.
– Geoff H
Jul 23 '18 at 23:10
add a comment |
unarchiveTopLevelObjectWithData(_:)
is deprecated as well. So to unarchive data without secure coding you need to:
- Create
NSKeyedUnarchiverwithinit(forReadingFrom: Data) - Set
requiresSecureCodingof created unarchiver to false. - Call
decodeObject(of: [AnyClass]?, forKey: String) -> Any?to get your object, just use proper class andNSKeyedArchiveRootObjectKeyas key.
add a comment |
if #available(iOS 12.0, *)
guard let unarchivedFavorites = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(favoritesData!)
else
return
self.channelFavorites = unarchivedFavorites as! [ChannelFavorite]
else {
if let unarchivedFavorites = NSKeyedUnarchiver.unarchiveObject(with: favoritesData!) as? [ChannelFavorite]
self.channelFavorites = unarchivedFavorites
// Achieving data
if #available(iOS 12.0, *)
// use iOS 12-only feature
do
let data = try NSKeyedArchiver.archivedData(withRootObject: channelFavorites, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "channelFavorites")
catch
return
else
// handle older versions
let data = NSKeyedArchiver.archivedData(withRootObject: channelFavorites)
UserDefaults.standard.set(data, forKey: "channelFavorites")
This is the way I have updated my code and its working for me
add a comment |
You are likely looking for this:
if let widgetsData = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
if let widgets = (try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, WidgetData.self], from: widgetsData)) as? [WidgetData]
// your code
I could resolve a same problem with your approach using ‘[NSArray.self, WidgetData.self]’. However I cound not find a public document about your approach. Do you know document url?
– Mao Nishi
Dec 6 '18 at 8:29
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51487622%2funarchive-array-with-nskeyedunarchiver-unarchivedobjectofclassfrom%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can use unarchiveTopLevelObjectWithData(_:) to unarchive the data archived by archivedData(withRootObject:requiringSecureCoding:). (I believe this is not deprecated yet.)
But before showing some code, you should better:
Avoid using
NSData, useDatainsteadAvoid using
try?which disposes error info useful for debuggingRemove all unneeded casts
Try this:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data
do
let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)
return data
catch
fatalError("Can't encode data: (error)")
static func loadWidgetDataArray() -> [WidgetData]?
guard
isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
else
return nil
do
guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else
fatalError("loadWidgetDataArray - Can't get Array")
return array
catch
fatalError("loadWidgetDataArray - Can't encode data: (error)")
But if you are making a new app, you should better consider using Codable.
That hit the nail on the head. Thank you so much. Yes, I'm making a new app. If you could shed a little light on Codable.. You got my attention. Where should I start with it & why is it important.
– Geoff H
Jul 23 '18 at 23:03
2
@GeoffH, it's native Swift way of serializing (archiving). (For example, it works with[WidgetData].self, you have no need to care aboutNSArrayor some otherNS-things.) Better start with searching "swift codable" and you can find many good articles.
– OOPer
Jul 23 '18 at 23:08
Will do. Thank you so much for your help.
– Geoff H
Jul 23 '18 at 23:10
add a comment |
You can use unarchiveTopLevelObjectWithData(_:) to unarchive the data archived by archivedData(withRootObject:requiringSecureCoding:). (I believe this is not deprecated yet.)
But before showing some code, you should better:
Avoid using
NSData, useDatainsteadAvoid using
try?which disposes error info useful for debuggingRemove all unneeded casts
Try this:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data
do
let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)
return data
catch
fatalError("Can't encode data: (error)")
static func loadWidgetDataArray() -> [WidgetData]?
guard
isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
else
return nil
do
guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else
fatalError("loadWidgetDataArray - Can't get Array")
return array
catch
fatalError("loadWidgetDataArray - Can't encode data: (error)")
But if you are making a new app, you should better consider using Codable.
That hit the nail on the head. Thank you so much. Yes, I'm making a new app. If you could shed a little light on Codable.. You got my attention. Where should I start with it & why is it important.
– Geoff H
Jul 23 '18 at 23:03
2
@GeoffH, it's native Swift way of serializing (archiving). (For example, it works with[WidgetData].self, you have no need to care aboutNSArrayor some otherNS-things.) Better start with searching "swift codable" and you can find many good articles.
– OOPer
Jul 23 '18 at 23:08
Will do. Thank you so much for your help.
– Geoff H
Jul 23 '18 at 23:10
add a comment |
You can use unarchiveTopLevelObjectWithData(_:) to unarchive the data archived by archivedData(withRootObject:requiringSecureCoding:). (I believe this is not deprecated yet.)
But before showing some code, you should better:
Avoid using
NSData, useDatainsteadAvoid using
try?which disposes error info useful for debuggingRemove all unneeded casts
Try this:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data
do
let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)
return data
catch
fatalError("Can't encode data: (error)")
static func loadWidgetDataArray() -> [WidgetData]?
guard
isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
else
return nil
do
guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else
fatalError("loadWidgetDataArray - Can't get Array")
return array
catch
fatalError("loadWidgetDataArray - Can't encode data: (error)")
But if you are making a new app, you should better consider using Codable.
You can use unarchiveTopLevelObjectWithData(_:) to unarchive the data archived by archivedData(withRootObject:requiringSecureCoding:). (I believe this is not deprecated yet.)
But before showing some code, you should better:
Avoid using
NSData, useDatainsteadAvoid using
try?which disposes error info useful for debuggingRemove all unneeded casts
Try this:
private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data
do
let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)
return data
catch
fatalError("Can't encode data: (error)")
static func loadWidgetDataArray() -> [WidgetData]?
guard
isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
else
return nil
do
guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else
fatalError("loadWidgetDataArray - Can't get Array")
return array
catch
fatalError("loadWidgetDataArray - Can't encode data: (error)")
But if you are making a new app, you should better consider using Codable.
answered Jul 23 '18 at 22:40
OOPerOOPer
35.2k46487
35.2k46487
That hit the nail on the head. Thank you so much. Yes, I'm making a new app. If you could shed a little light on Codable.. You got my attention. Where should I start with it & why is it important.
– Geoff H
Jul 23 '18 at 23:03
2
@GeoffH, it's native Swift way of serializing (archiving). (For example, it works with[WidgetData].self, you have no need to care aboutNSArrayor some otherNS-things.) Better start with searching "swift codable" and you can find many good articles.
– OOPer
Jul 23 '18 at 23:08
Will do. Thank you so much for your help.
– Geoff H
Jul 23 '18 at 23:10
add a comment |
That hit the nail on the head. Thank you so much. Yes, I'm making a new app. If you could shed a little light on Codable.. You got my attention. Where should I start with it & why is it important.
– Geoff H
Jul 23 '18 at 23:03
2
@GeoffH, it's native Swift way of serializing (archiving). (For example, it works with[WidgetData].self, you have no need to care aboutNSArrayor some otherNS-things.) Better start with searching "swift codable" and you can find many good articles.
– OOPer
Jul 23 '18 at 23:08
Will do. Thank you so much for your help.
– Geoff H
Jul 23 '18 at 23:10
That hit the nail on the head. Thank you so much. Yes, I'm making a new app. If you could shed a little light on Codable.. You got my attention. Where should I start with it & why is it important.
– Geoff H
Jul 23 '18 at 23:03
That hit the nail on the head. Thank you so much. Yes, I'm making a new app. If you could shed a little light on Codable.. You got my attention. Where should I start with it & why is it important.
– Geoff H
Jul 23 '18 at 23:03
2
2
@GeoffH, it's native Swift way of serializing (archiving). (For example, it works with
[WidgetData].self, you have no need to care about NSArray or some other NS-things.) Better start with searching "swift codable" and you can find many good articles.– OOPer
Jul 23 '18 at 23:08
@GeoffH, it's native Swift way of serializing (archiving). (For example, it works with
[WidgetData].self, you have no need to care about NSArray or some other NS-things.) Better start with searching "swift codable" and you can find many good articles.– OOPer
Jul 23 '18 at 23:08
Will do. Thank you so much for your help.
– Geoff H
Jul 23 '18 at 23:10
Will do. Thank you so much for your help.
– Geoff H
Jul 23 '18 at 23:10
add a comment |
unarchiveTopLevelObjectWithData(_:)
is deprecated as well. So to unarchive data without secure coding you need to:
- Create
NSKeyedUnarchiverwithinit(forReadingFrom: Data) - Set
requiresSecureCodingof created unarchiver to false. - Call
decodeObject(of: [AnyClass]?, forKey: String) -> Any?to get your object, just use proper class andNSKeyedArchiveRootObjectKeyas key.
add a comment |
unarchiveTopLevelObjectWithData(_:)
is deprecated as well. So to unarchive data without secure coding you need to:
- Create
NSKeyedUnarchiverwithinit(forReadingFrom: Data) - Set
requiresSecureCodingof created unarchiver to false. - Call
decodeObject(of: [AnyClass]?, forKey: String) -> Any?to get your object, just use proper class andNSKeyedArchiveRootObjectKeyas key.
add a comment |
unarchiveTopLevelObjectWithData(_:)
is deprecated as well. So to unarchive data without secure coding you need to:
- Create
NSKeyedUnarchiverwithinit(forReadingFrom: Data) - Set
requiresSecureCodingof created unarchiver to false. - Call
decodeObject(of: [AnyClass]?, forKey: String) -> Any?to get your object, just use proper class andNSKeyedArchiveRootObjectKeyas key.
unarchiveTopLevelObjectWithData(_:)
is deprecated as well. So to unarchive data without secure coding you need to:
- Create
NSKeyedUnarchiverwithinit(forReadingFrom: Data) - Set
requiresSecureCodingof created unarchiver to false. - Call
decodeObject(of: [AnyClass]?, forKey: String) -> Any?to get your object, just use proper class andNSKeyedArchiveRootObjectKeyas key.
answered Sep 20 '18 at 22:34
Maciej SMaciej S
121110
121110
add a comment |
add a comment |
if #available(iOS 12.0, *)
guard let unarchivedFavorites = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(favoritesData!)
else
return
self.channelFavorites = unarchivedFavorites as! [ChannelFavorite]
else {
if let unarchivedFavorites = NSKeyedUnarchiver.unarchiveObject(with: favoritesData!) as? [ChannelFavorite]
self.channelFavorites = unarchivedFavorites
// Achieving data
if #available(iOS 12.0, *)
// use iOS 12-only feature
do
let data = try NSKeyedArchiver.archivedData(withRootObject: channelFavorites, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "channelFavorites")
catch
return
else
// handle older versions
let data = NSKeyedArchiver.archivedData(withRootObject: channelFavorites)
UserDefaults.standard.set(data, forKey: "channelFavorites")
This is the way I have updated my code and its working for me
add a comment |
if #available(iOS 12.0, *)
guard let unarchivedFavorites = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(favoritesData!)
else
return
self.channelFavorites = unarchivedFavorites as! [ChannelFavorite]
else {
if let unarchivedFavorites = NSKeyedUnarchiver.unarchiveObject(with: favoritesData!) as? [ChannelFavorite]
self.channelFavorites = unarchivedFavorites
// Achieving data
if #available(iOS 12.0, *)
// use iOS 12-only feature
do
let data = try NSKeyedArchiver.archivedData(withRootObject: channelFavorites, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "channelFavorites")
catch
return
else
// handle older versions
let data = NSKeyedArchiver.archivedData(withRootObject: channelFavorites)
UserDefaults.standard.set(data, forKey: "channelFavorites")
This is the way I have updated my code and its working for me
add a comment |
if #available(iOS 12.0, *)
guard let unarchivedFavorites = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(favoritesData!)
else
return
self.channelFavorites = unarchivedFavorites as! [ChannelFavorite]
else {
if let unarchivedFavorites = NSKeyedUnarchiver.unarchiveObject(with: favoritesData!) as? [ChannelFavorite]
self.channelFavorites = unarchivedFavorites
// Achieving data
if #available(iOS 12.0, *)
// use iOS 12-only feature
do
let data = try NSKeyedArchiver.archivedData(withRootObject: channelFavorites, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "channelFavorites")
catch
return
else
// handle older versions
let data = NSKeyedArchiver.archivedData(withRootObject: channelFavorites)
UserDefaults.standard.set(data, forKey: "channelFavorites")
This is the way I have updated my code and its working for me
if #available(iOS 12.0, *)
guard let unarchivedFavorites = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(favoritesData!)
else
return
self.channelFavorites = unarchivedFavorites as! [ChannelFavorite]
else {
if let unarchivedFavorites = NSKeyedUnarchiver.unarchiveObject(with: favoritesData!) as? [ChannelFavorite]
self.channelFavorites = unarchivedFavorites
// Achieving data
if #available(iOS 12.0, *)
// use iOS 12-only feature
do
let data = try NSKeyedArchiver.archivedData(withRootObject: channelFavorites, requiringSecureCoding: false)
UserDefaults.standard.set(data, forKey: "channelFavorites")
catch
return
else
// handle older versions
let data = NSKeyedArchiver.archivedData(withRootObject: channelFavorites)
UserDefaults.standard.set(data, forKey: "channelFavorites")
This is the way I have updated my code and its working for me
answered Oct 23 '18 at 9:35
user1828845user1828845
9019
9019
add a comment |
add a comment |
You are likely looking for this:
if let widgetsData = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
if let widgets = (try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, WidgetData.self], from: widgetsData)) as? [WidgetData]
// your code
I could resolve a same problem with your approach using ‘[NSArray.self, WidgetData.self]’. However I cound not find a public document about your approach. Do you know document url?
– Mao Nishi
Dec 6 '18 at 8:29
add a comment |
You are likely looking for this:
if let widgetsData = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
if let widgets = (try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, WidgetData.self], from: widgetsData)) as? [WidgetData]
// your code
I could resolve a same problem with your approach using ‘[NSArray.self, WidgetData.self]’. However I cound not find a public document about your approach. Do you know document url?
– Mao Nishi
Dec 6 '18 at 8:29
add a comment |
You are likely looking for this:
if let widgetsData = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
if let widgets = (try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, WidgetData.self], from: widgetsData)) as? [WidgetData]
// your code
You are likely looking for this:
if let widgetsData = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
if let widgets = (try? NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, WidgetData.self], from: widgetsData)) as? [WidgetData]
// your code
answered Oct 11 '18 at 11:26
HopreeeenjustHopreeeenjust
10714
10714
I could resolve a same problem with your approach using ‘[NSArray.self, WidgetData.self]’. However I cound not find a public document about your approach. Do you know document url?
– Mao Nishi
Dec 6 '18 at 8:29
add a comment |
I could resolve a same problem with your approach using ‘[NSArray.self, WidgetData.self]’. However I cound not find a public document about your approach. Do you know document url?
– Mao Nishi
Dec 6 '18 at 8:29
I could resolve a same problem with your approach using ‘[NSArray.self, WidgetData.self]’. However I cound not find a public document about your approach. Do you know document url?
– Mao Nishi
Dec 6 '18 at 8:29
I could resolve a same problem with your approach using ‘[NSArray.self, WidgetData.self]’. However I cound not find a public document about your approach. Do you know document url?
– Mao Nishi
Dec 6 '18 at 8:29
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51487622%2funarchive-array-with-nskeyedunarchiver-unarchivedobjectofclassfrom%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Check this for a more swifty solution stackoverflow.com/a/51460950/5820010
– Sh_Khan
Jul 23 '18 at 21:53
What "fails"? What output do you get? You aren't using
Array.selfanywhere.– Paulw11
Jul 23 '18 at 22:34
When changed to Array.self instead of NSArray.self, the pre-compiler complains: Incorrect argument label in call (have 'ofClass:from:', expected 'ofClasses:from:') Replace 'ofClass' with 'ofClasses'. Which implies Array.self can't be used. When I use NSArray.self it compiles without issue & runs. But gets caught by the fatal error as the resulting 'nsArray' is nil.
– Geoff H
Jul 23 '18 at 22:38
So, what happens when you use
NSKeyedUnarchiver.unarchivedObject(ofClasses: [Array<WidgetData>.self], from: unarchivedObject as Data)? Also, instead of usingtry?usedo/try/catchso that you can print the actual error that occurred.– Paulw11
Jul 23 '18 at 22:45
It results in the following complaint: Cannot convert value of type 'Array<WidgetData>.Type' to expected element type 'AnyObject.Type' Insert ' as! AnyObject.Type'
– Geoff H
Jul 23 '18 at 22:59