Files
swift-mirror/stdlib/public/Darwin/Foundation/NSCoder.swift
Saleem Abdulrasool 41d9c2cc59 stdlib: restructure for OS family layout of SDK overlay
The SDK directory is now confusing as the Windows target also has a SDK
overlay.  In order to make this more uniform, move the SDK directory to
Darwin which covers the fact that this covers the XNU family of OSes.
The Windows directory contains the SDK overlay for the Windows target.
2018-12-06 11:32:05 -08:00

232 lines
8.0 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
@_exported import Foundation // Clang module
import _SwiftFoundationOverlayShims
//===----------------------------------------------------------------------===//
// NSCoder
//===----------------------------------------------------------------------===//
@available(macOS 10.11, iOS 9.0, *)
internal func resolveError(_ error: NSError?) throws {
if let error = error, error.code != NSCoderValueNotFoundError {
throw error
}
}
extension NSCoder {
@available(*, unavailable, renamed: "decodeObject(of:forKey:)")
public func decodeObjectOfClass<DecodedObjectType>(
_ cls: DecodedObjectType.Type, forKey key: String
) -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
fatalError("This API has been renamed")
}
public func decodeObject<DecodedObjectType>(
of cls: DecodedObjectType.Type, forKey key: String
) -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
let result = __NSCoderDecodeObjectOfClassForKey(self, cls, key, nil)
return result as? DecodedObjectType
}
@available(*, unavailable, renamed: "decodeObject(of:forKey:)")
@nonobjc
public func decodeObjectOfClasses(_ classes: NSSet?, forKey key: String) -> AnyObject? {
fatalError("This API has been renamed")
}
@nonobjc
public func decodeObject(of classes: [AnyClass]?, forKey key: String) -> Any? {
var classesAsNSObjects: NSSet?
if let theClasses = classes {
classesAsNSObjects = NSSet(array: theClasses.map { $0 as AnyObject })
}
return __NSCoderDecodeObjectOfClassesForKey(self, classesAsNSObjects, key, nil).map { $0 as Any }
}
@nonobjc
@available(macOS 10.11, iOS 9.0, *)
public func decodeTopLevelObject() throws -> Any? {
var error: NSError?
let result = __NSCoderDecodeObject(self, &error)
try resolveError(error)
return result.map { $0 as Any }
}
@available(*, unavailable, renamed: "decodeTopLevelObject(forKey:)")
public func decodeTopLevelObjectForKey(_ key: String) throws -> AnyObject? {
fatalError("This API has been renamed")
}
@nonobjc
@available(swift, obsoleted: 4)
@available(macOS 10.11, iOS 9.0, *)
public func decodeTopLevelObject(forKey key: String) throws -> AnyObject? {
var error: NSError?
let result = __NSCoderDecodeObjectForKey(self, key, &error)
try resolveError(error)
return result as AnyObject?
}
@nonobjc
@available(swift, introduced: 4)
@available(macOS 10.11, iOS 9.0, *)
public func decodeTopLevelObject(forKey key: String) throws -> Any? {
var error: NSError?
let result = __NSCoderDecodeObjectForKey(self, key, &error)
try resolveError(error)
return result
}
@available(*, unavailable, renamed: "decodeTopLevelObject(of:forKey:)")
public func decodeTopLevelObjectOfClass<DecodedObjectType>(
_ cls: DecodedObjectType.Type, forKey key: String
) throws -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
fatalError("This API has been renamed")
}
@available(macOS 10.11, iOS 9.0, *)
public func decodeTopLevelObject<DecodedObjectType>(
of cls: DecodedObjectType.Type, forKey key: String
) throws -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
var error: NSError?
let result = __NSCoderDecodeObjectOfClassForKey(self, cls, key, &error)
try resolveError(error)
return result as? DecodedObjectType
}
@nonobjc
@available(*, unavailable, renamed: "decodeTopLevelObject(of:forKey:)")
public func decodeTopLevelObjectOfClasses(_ classes: NSSet?, forKey key: String) throws -> AnyObject? {
fatalError("This API has been renamed")
}
@nonobjc
@available(macOS 10.11, iOS 9.0, *)
public func decodeTopLevelObject(of classes: [AnyClass]?, forKey key: String) throws -> Any? {
var error: NSError?
var classesAsNSObjects: NSSet?
if let theClasses = classes {
classesAsNSObjects = NSSet(array: theClasses.map { $0 as AnyObject })
}
let result = __NSCoderDecodeObjectOfClassesForKey(self, classesAsNSObjects, key, &error)
try resolveError(error)
return result.map { $0 as Any }
}
}
//===----------------------------------------------------------------------===//
// NSKeyedArchiver
//===----------------------------------------------------------------------===//
extension NSKeyedArchiver {
@nonobjc
@available(macOS 10.11, iOS 9.0, *)
public func encodeEncodable<T : Encodable>(_ value: T, forKey key: String) throws {
let plistEncoder = PropertyListEncoder()
let plist = try plistEncoder.encodeToTopLevelContainer(value)
self.encode(plist, forKey: key)
}
}
//===----------------------------------------------------------------------===//
// NSKeyedUnarchiver
//===----------------------------------------------------------------------===//
extension NSKeyedUnarchiver {
@nonobjc
@available(swift, obsoleted: 4)
@available(macOS 10.11, iOS 9.0, *)
public class func unarchiveTopLevelObjectWithData(_ data: NSData) throws -> AnyObject? {
var error: NSError?
let result = __NSKeyedUnarchiverUnarchiveObject(self, data, &error)
try resolveError(error)
return result as AnyObject?
}
@nonobjc
@available(swift, introduced: 4)
@available(macOS 10.11, iOS 9.0, *)
public class func unarchiveTopLevelObjectWithData(_ data: Data) throws -> Any? {
var error: NSError?
let result = __NSKeyedUnarchiverUnarchiveObject(self, data as NSData, &error)
try resolveError(error)
return result
}
@nonobjc
@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
public static func unarchivedObject<DecodedObjectType>(ofClass cls: DecodedObjectType.Type, from data: Data) throws -> DecodedObjectType? where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
var error: NSError?
let result = __NSKeyedUnarchiverSecureUnarchiveObjectOfClass(cls as AnyClass, data, &error)
if let error = error { throw error }
return result as? DecodedObjectType
}
@nonobjc
@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
public static func unarchivedObject(ofClasses classes: [AnyClass], from data: Data) throws -> Any? {
var error: NSError?
let classesAsNSObjects = NSSet(array: classes.map { $0 as AnyObject })
let result = __NSKeyedUnarchiverSecureUnarchiveObjectOfClasses(classesAsNSObjects, data, &error)
if let error = error { throw error }
return result
}
@nonobjc
private static let __plistClasses: [AnyClass] = [
NSArray.self,
NSData.self,
NSDate.self,
NSDictionary.self,
NSNumber.self,
NSString.self
]
@nonobjc
@available(macOS 10.11, iOS 9.0, *)
public func decodeDecodable<T : Decodable>(_ type: T.Type, forKey key: String) -> T? {
guard let value = self.decodeObject(of: NSKeyedUnarchiver.__plistClasses, forKey: key) else {
return nil
}
let plistDecoder = PropertyListDecoder()
do {
return try plistDecoder.decode(T.self, fromTopLevel: value)
} catch {
self.failWithError(error)
return nil
}
}
@nonobjc
@available(macOS 10.11, iOS 9.0, *)
public func decodeTopLevelDecodable<T : Decodable>(_ type: T.Type, forKey key: String) throws -> T? {
guard let value = try self.decodeTopLevelObject(of: NSKeyedUnarchiver.__plistClasses, forKey: key) else {
return nil
}
let plistDecoder = PropertyListDecoder()
do {
return try plistDecoder.decode(T.self, fromTopLevel: value)
} catch {
self.failWithError(error)
throw error;
}
}
}