Skip to content

Commit 567fd93

Browse files
author
Brian King
committed
Merge branch 'master' into bugfix/SR-2301
2 parents b3955c2 + 013943a commit 567fd93

File tree

4 files changed

+81
-33
lines changed

4 files changed

+81
-33
lines changed

Foundation/Locale.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public struct Locale : CustomStringConvertible, CustomDebugStringConvertible, Ha
6969

7070
/// Returns a localized string for a specified identifier.
7171
///
72-
/// For example, in the "en" locale, the result for `"en"` is `"Spanish"`.
72+
/// For example, in the "en" locale, the result for `"es"` is `"Spanish"`.
7373
public func localizedString(forIdentifier identifier: String) -> String? {
7474
return _wrapped.displayName(forKey: .identifier, value: identifier)
7575
}
@@ -83,7 +83,7 @@ public struct Locale : CustomStringConvertible, CustomDebugStringConvertible, Ha
8383

8484
/// Returns a localized string for a specified region code.
8585
///
86-
/// For example, in the "en" locale, the result for `"fr"` is `"French"`.
86+
/// For example, in the "en" locale, the result for `"fr"` is `"France"`.
8787
public func localizedString(forRegionCode regionCode: String) -> String? {
8888
return _wrapped.displayName(forKey: .countryCode, value: regionCode)
8989
}

Foundation/NSKeyedArchiver.swift

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,17 @@ open class NSKeyedArchiver : NSCoder {
270270
return NSKeyedArchiveNullObjectReference
271271
}
272272

273-
uid = self._objRefMap[objv as! AnyHashable]
273+
let value = _SwiftValue.store(objv)!
274+
275+
uid = self._objRefMap[value]
274276
if uid == nil {
275277
if conditional {
276278
return nil // object has not been unconditionally encoded
277279
}
278280

279281
uid = UInt32(self._objects.count)
280282

281-
self._objRefMap[objv as! AnyHashable] = uid
283+
self._objRefMap[value] = uid
282284
self._objects.insert(NSKeyedArchiveNullObjectReferenceName, at: Int(uid!))
283285
}
284286

@@ -292,7 +294,7 @@ open class NSKeyedArchiver : NSCoder {
292294
if objv == nil {
293295
return true // always have a null reference
294296
} else {
295-
return self._objRefMap[objv as! AnyHashable] != nil
297+
return self._objRefMap[_SwiftValue.store(objv)] != nil
296298
}
297299
}
298300

@@ -361,10 +363,10 @@ open class NSKeyedArchiver : NSCoder {
361363
*/
362364
private func replaceObject(_ object: Any, withObject replacement: Any?) {
363365
if let unwrappedDelegate = self.delegate {
364-
unwrappedDelegate.archiver(self, willReplace: object as! AnyHashable, with: replacement)
366+
unwrappedDelegate.archiver(self, willReplace: object, with: replacement)
365367
}
366368

367-
self._replacementMap[object as! AnyHashable] = replacement
369+
self._replacementMap[_SwiftValue.store(object)] = replacement
368370
}
369371

370372
/**
@@ -476,9 +478,8 @@ open class NSKeyedArchiver : NSCoder {
476478

477479
// object replaced by NSObject.replacementObjectForKeyedArchiver
478480
// if it is replaced with nil, it cannot be further replaced
479-
if objectToEncode == nil {
480-
let ns = object as? NSObject
481-
objectToEncode = ns?.replacementObjectForKeyedArchiver(self)
481+
if let ns = objectToEncode as? NSObject {
482+
objectToEncode = ns.replacementObjectForKeyedArchiver(self)
482483
if objectToEncode == nil {
483484
replaceObject(object!, withObject: nil)
484485
return nil
@@ -510,7 +511,12 @@ open class NSKeyedArchiver : NSCoder {
510511

511512
haveVisited = _haveVisited(objv)
512513
object = _replacementObject(objv)
513-
514+
515+
// bridge value types
516+
if let bridgedObject = object as? _ObjectBridgeable {
517+
object = bridgedObject._bridgeToAnyObject()
518+
}
519+
514520
objectRef = _referenceObject(object, conditional: conditional)
515521
guard let unwrappedObjectRef = objectRef else {
516522
// we can return nil if the object is being conditionally encoded
@@ -531,12 +537,9 @@ open class NSKeyedArchiver : NSCoder {
531537
_pushEncodingContext(innerEncodingContext)
532538
codable.encode(with: self)
533539

534-
guard let ns = object as? NSObject else {
535-
fatalError("Attempt to encode non-NSObject");
536-
}
537-
538-
let cls : AnyClass = ns.classForKeyedArchiver ?? type(of: object) as! AnyClass
539-
540+
let ns = object as? NSObject
541+
let cls : AnyClass = ns?.classForKeyedArchiver ?? type(of: object!) as! AnyClass
542+
540543
_setObjectInCurrentEncodingContext(_classReference(cls), forKey: "$class", escape: false)
541544
_popEncodingContext()
542545
encodedObject = innerEncodingContext.dict

Foundation/NSKeyedUnarchiver.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ open class NSKeyedUnarchiver : NSCoder {
375375
unwrappedDelegate.unarchiver(self, willReplace: object, with: replacement)
376376
}
377377

378-
self._replacementMap[object as! AnyHashable] = replacement
378+
self._replacementMap[_SwiftValue.store(object)] = replacement
379379
}
380380

381381
private func _decodingError(_ code: CocoaError.Code, withDescription description: String) -> NSError {
@@ -392,7 +392,7 @@ open class NSKeyedUnarchiver : NSCoder {
392392
}
393393

394394
// check replacement cache
395-
object = self._replacementMap[decodedObject as! AnyHashable]
395+
object = self._replacementMap[_SwiftValue.store(decodedObject)]
396396
if object != nil {
397397
return object
398398
}
@@ -489,9 +489,8 @@ open class NSKeyedUnarchiver : NSCoder {
489489
}
490490
} else {
491491
// reference to a non-container object
492-
// FIXME remove these special cases
493-
if let str = dereferencedObject as? String {
494-
object = str._bridgeToObjectiveC()
492+
if let bridgedObject = dereferencedObject as? _ObjectBridgeable {
493+
object = bridgedObject._bridgeToAnyObject()
495494
} else {
496495
object = dereferencedObject
497496
}

TestFoundation/TestNSKeyedArchiver.swift

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import SwiftXCTest
1717
#endif
1818

19-
public class UserClass : NSObject, NSSecureCoding {
19+
public class NSUserClass : NSObject, NSSecureCoding {
2020
var ivar : Int
2121

2222
public class var supportsSecureCoding: Bool {
@@ -37,19 +37,53 @@ public class UserClass : NSObject, NSSecureCoding {
3737

3838
public override var description: String {
3939
get {
40-
return "UserClass \(ivar)"
40+
return "NSUserClass \(ivar)"
4141
}
4242
}
4343

4444
public override func isEqual(_ object: Any?) -> Bool {
45-
if let custom = object as? UserClass {
45+
if let custom = object as? NSUserClass {
4646
return self.ivar == custom.ivar
4747
} else {
4848
return false
4949
}
5050
}
5151
}
5252

53+
public class UserClass : CustomStringConvertible, Equatable, Hashable, NSSecureCoding {
54+
var ivar : Int
55+
56+
public class var supportsSecureCoding: Bool {
57+
return true
58+
}
59+
60+
public func encode(with aCoder : NSCoder) {
61+
aCoder.encode(ivar, forKey:"$ivar") // also test escaping
62+
}
63+
64+
init(_ value: Int) {
65+
self.ivar = value
66+
}
67+
68+
public required init?(coder aDecoder: NSCoder) {
69+
self.ivar = aDecoder.decodeInteger(forKey: "$ivar")
70+
}
71+
72+
public var description: String {
73+
get {
74+
return "UserClass \(ivar)"
75+
}
76+
}
77+
78+
public static func ==(lhs: UserClass, rhs: UserClass) -> Bool {
79+
return lhs.ivar == rhs.ivar
80+
}
81+
82+
public var hashValue: Int {
83+
return ivar
84+
}
85+
}
86+
5387
class TestNSKeyedArchiver : XCTestCase {
5488
static var allTests: [(String, (TestNSKeyedArchiver) -> () throws -> Void)] {
5589
return [
@@ -62,14 +96,16 @@ class TestNSKeyedArchiver : XCTestCase {
6296
("test_archive_string", test_archive_string),
6397
("test_archive_mutable_array", test_archive_mutable_array),
6498
("test_archive_mutable_dictionary", test_archive_mutable_dictionary),
99+
("test_archive_ns_user_class", test_archive_ns_user_class),
65100
("test_archive_nspoint", test_archive_nspoint),
66101
("test_archive_nsrange", test_archive_nsrange),
67102
("test_archive_nsrect", test_archive_nsrect),
68103
("test_archive_null", test_archive_null),
69104
("test_archive_set", test_archive_set),
70105
("test_archive_url", test_archive_url),
71106
("test_archive_user_class", test_archive_user_class),
72-
("test_archive_uuid", test_archive_uuid),
107+
("test_archive_uuid_bvref", test_archive_uuid_byref),
108+
("test_archive_uuid_byvalue", test_archive_uuid_byvalue),
73109
]
74110
}
75111

@@ -85,7 +121,7 @@ class TestNSKeyedArchiver : XCTestCase {
85121
XCTAssertTrue(decode(unarchiver))
86122
}
87123

88-
private func test_archive(_ object: NSObject, classes: [AnyClass], allowsSecureCoding: Bool = true, outputFormat: PropertyListSerialization.PropertyListFormat) {
124+
private func test_archive(_ object: Any, classes: [AnyClass], allowsSecureCoding: Bool = true, outputFormat: PropertyListSerialization.PropertyListFormat) {
89125
test_archive({ archiver -> Bool in
90126
archiver.requiresSecureCoding = allowsSecureCoding
91127
archiver.outputFormat = outputFormat
@@ -97,26 +133,26 @@ class TestNSKeyedArchiver : XCTestCase {
97133
unarchiver.requiresSecureCoding = allowsSecureCoding
98134

99135
do {
100-
let rootObj = try unarchiver.decodeTopLevelObject(of: classes, forKey: NSKeyedArchiveRootObjectKey)
101-
guard let root = rootObj as? NSObject else {
136+
guard let rootObj = try unarchiver.decodeTopLevelObject(of: classes, forKey: NSKeyedArchiveRootObjectKey) else {
102137
XCTFail("Unable to decode data")
103138
return false
104139
}
105-
XCTAssertEqual(object, root, "unarchived object \(root) does not match \(object)")
140+
141+
XCTAssertEqual(object as? AnyHashable, rootObj as? AnyHashable, "unarchived object \(rootObj) does not match \(object)")
106142
} catch {
107143
XCTFail("Error thrown: \(error)")
108144
}
109145
return true
110146
})
111147
}
112148

113-
private func test_archive(_ object: NSObject, classes: [AnyClass], allowsSecureCoding: Bool = true) {
149+
private func test_archive(_ object: Any, classes: [AnyClass], allowsSecureCoding: Bool = true) {
114150
// test both XML and binary encodings
115151
test_archive(object, classes: classes, allowsSecureCoding: allowsSecureCoding, outputFormat: PropertyListSerialization.PropertyListFormat.xml)
116152
test_archive(object, classes: classes, allowsSecureCoding: allowsSecureCoding, outputFormat: PropertyListSerialization.PropertyListFormat.binary)
117153
}
118154

119-
private func test_archive(_ object: NSObject, allowsSecureCoding: Bool = true) {
155+
private func test_archive(_ object: AnyObject, allowsSecureCoding: Bool = true) {
120156
return test_archive(object, classes: [type(of: object)], allowsSecureCoding: allowsSecureCoding)
121157
}
122158

@@ -252,8 +288,18 @@ class TestNSKeyedArchiver : XCTestCase {
252288
test_archive(userClass)
253289
}
254290

255-
func test_archive_uuid() {
291+
func test_archive_ns_user_class() {
292+
let nsUserClass = NSUserClass(5678)
293+
test_archive(nsUserClass)
294+
}
295+
296+
func test_archive_uuid_byref() {
256297
let uuid = NSUUID()
257298
test_archive(uuid)
258299
}
300+
301+
func test_archive_uuid_byvalue() {
302+
let uuid = UUID()
303+
return test_archive(uuid, classes: [NSUUID.self])
304+
}
259305
}

0 commit comments

Comments
 (0)