| //===----------------------------------------------------------------------===// |
| // |
| // 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(OSX 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(OSX 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(OSX 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(OSX 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(OSX 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(OSX 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(OSX 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(OSX 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(OSX 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(OSX 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? { |
| var error: NSError? |
| let result = __NSKeyedUnarchiverSecureUnarchiveObjectOfClass(cls as! AnyClass, data, &error) |
| try resolveError(error) |
| return result as? DecodedObjectType |
| } |
| |
| @nonobjc |
| @available(OSX 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) |
| try resolveError(error) |
| return result |
| } |
| |
| @nonobjc |
| private static let __plistClasses: [AnyClass] = [ |
| NSArray.self, |
| NSData.self, |
| NSDate.self, |
| NSDictionary.self, |
| NSNumber.self, |
| NSString.self |
| ] |
| |
| @nonobjc |
| @available(OSX 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(OSX 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; |
| } |
| } |
| } |
| |
| |
| @available(*, deprecated, renamed:"NSCoding", message: "Please use NSCoding") |
| typealias Coding = NSCoding |
| |
| @available(*, deprecated, renamed:"NSCoder", message: "Please use NSCoder") |
| typealias Coder = NSCoder |
| |
| @available(*, deprecated, renamed:"NSKeyedUnarchiver", message: "Please use NSKeyedUnarchiver") |
| typealias KeyedUnarchiver = NSKeyedUnarchiver |
| |
| @available(*, deprecated, renamed:"NSKeyedArchiver", message: "Please use NSKeyedArchiver") |
| typealias KeyedArchiver = NSKeyedArchiver |