From f66ba5e7301a6b0d98c312ba695eaa7fdcf57d7a Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Wed, 23 Nov 2022 15:38:05 -0800 Subject: [PATCH] Revert "Revert "reland "Migrate darwin common "framework_shared" target to ARC #37049" (#37219)" (#37320)" This reverts commit cf22fc23f6b54d28b767708685d92154f8aefd68. --- shell/platform/darwin/BUILD.gn | 27 ++++-- shell/platform/darwin/common/BUILD.gn | 14 +-- .../common/framework/Headers/FlutterCodecs.h | 6 +- .../framework/Source/FlutterChannels.mm | 94 ++++++------------- .../framework/Source/FlutterChannelsTest.m | 72 ++++++++++++++ .../common/framework/Source/FlutterCodecs.mm | 4 +- .../framework/Source/FlutterStandardCodec.mm | 57 ++++------- .../Source/FlutterRestorationPluginTest.mm | 12 +-- 8 files changed, 154 insertions(+), 132 deletions(-) diff --git a/shell/platform/darwin/BUILD.gn b/shell/platform/darwin/BUILD.gn index 23c8e4055acf7..f11a8b7aa1cb1 100644 --- a/shell/platform/darwin/BUILD.gn +++ b/shell/platform/darwin/BUILD.gn @@ -26,6 +26,20 @@ source_set("flutter_channels") { sources = [ "common/buffer_conversions.h", "common/buffer_conversions.mm", + ] + + deps = [ "//flutter/fml" ] + + public_deps = [ ":flutter_channels_arc" ] + + public_configs = [ "//flutter:config" ] +} + +source_set("flutter_channels_arc") { + cflags_objc = flutter_cflags_objc_arc + cflags_objcc = flutter_cflags_objcc_arc + + sources = [ "common/framework/Headers/FlutterBinaryMessenger.h", "common/framework/Headers/FlutterChannels.h", "common/framework/Headers/FlutterCodecs.h", @@ -36,13 +50,12 @@ source_set("flutter_channels") { "common/framework/Source/FlutterStandardCodec_Internal.h", ] - deps = [ - "//flutter/common", - "//flutter/flow", - "//flutter/fml", - "//flutter/runtime", - "//flutter/shell/common", - "//third_party/skia", + public = [ + "common/framework/Headers/FlutterBinaryMessenger.h", + "common/framework/Headers/FlutterChannels.h", + "common/framework/Headers/FlutterCodecs.h", + "common/framework/Headers/FlutterMacros.h", + "common/framework/Source/FlutterStandardCodec_Internal.h", ] public_configs = [ "//flutter:config" ] diff --git a/shell/platform/darwin/common/BUILD.gn b/shell/platform/darwin/common/BUILD.gn index 45a9e3092b2bc..72e3a807f1d85 100644 --- a/shell/platform/darwin/common/BUILD.gn +++ b/shell/platform/darwin/common/BUILD.gn @@ -16,15 +16,7 @@ source_set("common") { "command_line.mm", ] - deps = [ - "//flutter/common", - "//flutter/flow", - "//flutter/fml", - "//flutter/runtime", - "//flutter/shell/common", - "//third_party/dart/runtime:dart_api", - "//third_party/skia", - ] + deps = [ "//flutter/fml" ] public_configs = [ "//flutter:config" ] } @@ -38,8 +30,8 @@ config("framework_relative_headers") { # Framework code shared between iOS and macOS. source_set("framework_shared") { - cflags_objc = flutter_cflags_objc - cflags_objcc = flutter_cflags_objcc + cflags_objc = flutter_cflags_objc_arc + cflags_objcc = flutter_cflags_objcc_arc sources = [ "framework/Source/FlutterChannels.mm", diff --git a/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h b/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h index 3ba5d4e9c2580..f7117f01ffb7a 100644 --- a/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h +++ b/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h @@ -344,17 +344,17 @@ FLUTTER_DARWIN_EXPORT /** * The type of the encoded values. */ -@property(readonly, nonatomic) FlutterStandardDataType type; +@property(readonly, nonatomic, assign) FlutterStandardDataType type; /** * The number of value items encoded. */ -@property(readonly, nonatomic) UInt32 elementCount; +@property(readonly, nonatomic, assign) UInt32 elementCount; /** * The number of bytes used by the encoding of a single value item. */ -@property(readonly, nonatomic) UInt8 elementSize; +@property(readonly, nonatomic, assign) UInt8 elementSize; @end /** diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm index 30b306a301f39..f360144d3748f 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannels.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterChannels.mm @@ -4,6 +4,8 @@ #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" +FLUTTER_ASSERT_ARC + #pragma mark - Basic message channel static NSString* const kFlutterChannelBuffersChannel = @"dev.flutter/channel-buffers"; @@ -51,9 +53,9 @@ + (instancetype)messageChannelWithName:(NSString*)name + (instancetype)messageChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[[FlutterBasicMessageChannel alloc] initWithName:name - binaryMessenger:messenger - codec:codec] autorelease]; + return [[FlutterBasicMessageChannel alloc] initWithName:name + binaryMessenger:messenger + codec:codec]; } - (instancetype)initWithName:(NSString*)name @@ -69,21 +71,13 @@ - (instancetype)initWithName:(NSString*)name taskQueue:(NSObject*)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _name = [name retain]; - _messenger = [messenger retain]; - _codec = [codec retain]; - _taskQueue = [taskQueue retain]; + _name = [name copy]; + _messenger = messenger; + _codec = codec; + _taskQueue = taskQueue; return self; } -- (void)dealloc { - [_name release]; - [_messenger release]; - [_codec release]; - [_taskQueue release]; - [super dealloc]; -} - - (void)sendMessage:(id)message { [_messenger sendOnChannel:_name message:[_codec encode:message]]; } @@ -107,7 +101,10 @@ - (void)setMessageHandler:(FlutterMessageHandler)handler { } return; } + // Grab reference to avoid retain on self. + // `self` might be released before the block, so the block needs to retain the codec to + // make sure it is not released with `self` NSObject* codec = _codec; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { handler([codec decode:message], ^(id reply) { @@ -128,26 +125,19 @@ - (void)resizeChannelBuffer:(NSInteger)newSize { //////////////////////////////////////////////////////////////////////////////// @implementation FlutterError + (instancetype)errorWithCode:(NSString*)code message:(NSString*)message details:(id)details { - return [[[FlutterError alloc] initWithCode:code message:message details:details] autorelease]; + return [[FlutterError alloc] initWithCode:code message:message details:details]; } - (instancetype)initWithCode:(NSString*)code message:(NSString*)message details:(id)details { NSAssert(code, @"Code cannot be nil"); self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _code = [code retain]; - _message = [message retain]; - _details = [details retain]; + _code = [code copy]; + _message = [message copy]; + _details = details; return self; } -- (void)dealloc { - [_code release]; - [_message release]; - [_details release]; - [super dealloc]; -} - - (BOOL)isEqual:(id)object { if (self == object) { return YES; @@ -169,24 +159,18 @@ - (NSUInteger)hash { //////////////////////////////////////////////////////////////////////////////// @implementation FlutterMethodCall + (instancetype)methodCallWithMethodName:(NSString*)method arguments:(id)arguments { - return [[[FlutterMethodCall alloc] initWithMethodName:method arguments:arguments] autorelease]; + return [[FlutterMethodCall alloc] initWithMethodName:method arguments:arguments]; } - (instancetype)initWithMethodName:(NSString*)method arguments:(id)arguments { NSAssert(method, @"Method name cannot be nil"); self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _method = [method retain]; - _arguments = [arguments retain]; + _method = [method copy]; + _arguments = arguments; return self; } -- (void)dealloc { - [_method release]; - [_arguments release]; - [super dealloc]; -} - - (BOOL)isEqual:(id)object { if (self == object) { return YES; @@ -224,8 +208,7 @@ + (instancetype)methodChannelWithName:(NSString*)name + (instancetype)methodChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger - codec:codec] autorelease]; + return [[FlutterMethodChannel alloc] initWithName:name binaryMessenger:messenger codec:codec]; } - (instancetype)initWithName:(NSString*)name @@ -240,21 +223,13 @@ - (instancetype)initWithName:(NSString*)name taskQueue:(NSObject*)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _name = [name retain]; - _messenger = [messenger retain]; - _codec = [codec retain]; - _taskQueue = [taskQueue retain]; + _name = [name copy]; + _messenger = messenger; + _codec = codec; + _taskQueue = taskQueue; return self; } -- (void)dealloc { - [_name release]; - [_messenger release]; - [_codec release]; - [_taskQueue release]; - [super dealloc]; -} - - (void)invokeMethod:(NSString*)method arguments:(id)arguments { FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:method arguments:arguments]; @@ -285,6 +260,8 @@ - (void)setMethodCallHandler:(FlutterMethodCallHandler)handler { return; } // Make sure the block captures the codec, not self. + // `self` might be released before the block, so the block needs to retain the codec to + // make sure it is not released with `self` NSObject* codec = _codec; FlutterBinaryMessageHandler messageHandler = ^(NSData* message, FlutterBinaryReply callback) { FlutterMethodCall* call = [codec decodeMethodCall:message]; @@ -328,8 +305,7 @@ + (instancetype)eventChannelWithName:(NSString*)name + (instancetype)eventChannelWithName:(NSString*)name binaryMessenger:(NSObject*)messenger codec:(NSObject*)codec { - return [[[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger - codec:codec] autorelease]; + return [[FlutterEventChannel alloc] initWithName:name binaryMessenger:messenger codec:codec]; } - (instancetype)initWithName:(NSString*)name @@ -344,21 +320,13 @@ - (instancetype)initWithName:(NSString*)name taskQueue:(NSObject* _Nullable)taskQueue { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _name = [name retain]; - _messenger = [messenger retain]; - _codec = [codec retain]; - _taskQueue = [taskQueue retain]; + _name = [name copy]; + _messenger = messenger; + _codec = codec; + _taskQueue = taskQueue; return self; } -- (void)dealloc { - [_name release]; - [_codec release]; - [_messenger release]; - [_taskQueue release]; - [super dealloc]; -} - static FlutterBinaryMessengerConnection SetStreamHandlerMessageHandlerOnChannel( NSObject* handler, NSString* name, diff --git a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m index a499fbea8f34d..e2593f535b7e1 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m +++ b/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m @@ -234,6 +234,78 @@ - (void)testBasicMessageChannelTaskQueue { OCMVerify([binaryMessenger cleanUpConnection:connection]); } +- (void)testBasicMessageChannelInvokeHandlerAfterChannelReleased { + NSString* channelName = @"foo"; + __block NSString* handlerMessage; + __block FlutterBinaryMessageHandler messageHandler; + @autoreleasepool { + FlutterBinaryMessengerConnection connection = 123; + id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + id codec = OCMProtocolMock(@protocol(FlutterMessageCodec)); + id taskQueue = OCMClassMock([NSObject class]); + FlutterBasicMessageChannel* channel = + [[FlutterBasicMessageChannel alloc] initWithName:channelName + binaryMessenger:binaryMessenger + codec:codec + taskQueue:taskQueue]; + + FlutterMessageHandler handler = ^(id _Nullable message, FlutterReply callback) { + handlerMessage = message; + }; + OCMStub([binaryMessenger + setMessageHandlerOnChannel:channelName + binaryMessageHandler:[OCMArg checkWithBlock:^BOOL( + FlutterBinaryMessageHandler handler) { + messageHandler = handler; + return YES; + }] + taskQueue:taskQueue]) + .andReturn(connection); + OCMStub([codec decode:[OCMArg any]]).andReturn(@"decoded message"); + [channel setMessageHandler:handler]; + } + // Channel is released, messageHandler should still retain the codec. The codec + // internally makes a `decode` call and updates the `handlerMessage` to "decoded message". + messageHandler([NSData data], ^(NSData* data){ + }); + XCTAssertEqualObjects(handlerMessage, @"decoded message"); +} + +- (void)testMethodChannelInvokeHandlerAfterChannelReleased { + NSString* channelName = @"foo"; + FlutterBinaryMessengerConnection connection = 123; + __block FlutterMethodCall* decodedMethodCall; + __block FlutterBinaryMessageHandler messageHandler; + @autoreleasepool { + id binaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + id codec = OCMProtocolMock(@protocol(FlutterMethodCodec)); + id taskQueue = OCMClassMock([NSObject class]); + FlutterMethodChannel* channel = [[FlutterMethodChannel alloc] initWithName:channelName + binaryMessenger:binaryMessenger + codec:codec + taskQueue:taskQueue]; + FlutterMethodCallHandler handler = ^(FlutterMethodCall* call, FlutterResult result) { + decodedMethodCall = call; + }; + OCMStub([binaryMessenger + setMessageHandlerOnChannel:channelName + binaryMessageHandler:[OCMArg checkWithBlock:^BOOL( + FlutterBinaryMessageHandler handler) { + messageHandler = handler; + return YES; + }] + taskQueue:taskQueue]) + .andReturn(connection); + OCMStub([codec decodeMethodCall:[OCMArg any]]) + .andReturn([FlutterMethodCall methodCallWithMethodName:@"decoded method call" + arguments:nil]); + [channel setMethodCallHandler:handler]; + } + messageHandler([NSData data], ^(NSData* data){ + }); + XCTAssertEqualObjects(decodedMethodCall.method, @"decoded method call"); +} + - (void)testMethodChannelTaskQueue { NSString* channelName = @"foo"; FlutterBinaryMessengerConnection connection = 123; diff --git a/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm b/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm index 8ea26cc258063..57ef1eb752a4a 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm @@ -6,6 +6,8 @@ #include +FLUTTER_ASSERT_ARC + @implementation FlutterBinaryCodec + (instancetype)sharedInstance { static id _sharedInstance = nil; @@ -48,7 +50,7 @@ - (NSString*)decode:(NSData*)message { if (message == nil) { return nil; } - return [[[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding] autorelease]; + return [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding]; } @end diff --git a/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm b/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm index eeb3ef918b0c3..62e85e66a2440 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm @@ -4,6 +4,8 @@ #import "flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodec_Internal.h" +FLUTTER_ASSERT_ARC + #pragma mark - Codec for basic message channel @implementation FlutterStandardMessageCodec { @@ -12,29 +14,23 @@ @implementation FlutterStandardMessageCodec { + (instancetype)sharedInstance { static id _sharedInstance = nil; if (!_sharedInstance) { - FlutterStandardReaderWriter* readerWriter = - [[[FlutterStandardReaderWriter alloc] init] autorelease]; + FlutterStandardReaderWriter* readerWriter = [[FlutterStandardReaderWriter alloc] init]; _sharedInstance = [[FlutterStandardMessageCodec alloc] initWithReaderWriter:readerWriter]; } return _sharedInstance; } + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { - return [[[FlutterStandardMessageCodec alloc] initWithReaderWriter:readerWriter] autorelease]; + return [[FlutterStandardMessageCodec alloc] initWithReaderWriter:readerWriter]; } - (instancetype)initWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _readerWriter = [readerWriter retain]; + _readerWriter = readerWriter; return self; } -- (void)dealloc { - [_readerWriter release]; - [super dealloc]; -} - - (NSData*)encode:(id)message { if (message == nil) { return nil; @@ -64,29 +60,23 @@ @implementation FlutterStandardMethodCodec { + (instancetype)sharedInstance { static id _sharedInstance = nil; if (!_sharedInstance) { - FlutterStandardReaderWriter* readerWriter = - [[[FlutterStandardReaderWriter alloc] init] autorelease]; + FlutterStandardReaderWriter* readerWriter = [[FlutterStandardReaderWriter alloc] init]; _sharedInstance = [[FlutterStandardMethodCodec alloc] initWithReaderWriter:readerWriter]; } return _sharedInstance; } + (instancetype)codecWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { - return [[[FlutterStandardMethodCodec alloc] initWithReaderWriter:readerWriter] autorelease]; + return [[FlutterStandardMethodCodec alloc] initWithReaderWriter:readerWriter]; } - (instancetype)initWithReaderWriter:(FlutterStandardReaderWriter*)readerWriter { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _readerWriter = [readerWriter retain]; + _readerWriter = readerWriter; return self; } -- (void)dealloc { - [_readerWriter release]; - [super dealloc]; -} - - (NSData*)encodeMethodCall:(FlutterMethodCall*)call { NSMutableData* data = [NSMutableData dataWithCapacity:32]; FlutterStandardWriter* writer = [_readerWriter writerWithData:data]; @@ -173,7 +163,7 @@ + (instancetype)typedDataWithFloat64:(NSData*)data { } + (instancetype)typedDataWithData:(NSData*)data type:(FlutterStandardDataType)type { - return [[[FlutterStandardTypedData alloc] initWithData:data type:type] autorelease]; + return [[FlutterStandardTypedData alloc] initWithData:data type:type]; } - (instancetype)initWithData:(NSData*)data type:(FlutterStandardDataType)type { @@ -182,18 +172,13 @@ - (instancetype)initWithData:(NSData*)data type:(FlutterStandardDataType)type { NSAssert(data.length % elementSize == 0, @"Data must contain integral number of elements"); self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _data = [data retain]; + _data = [data copy]; _type = type; _elementSize = elementSize; _elementCount = data.length / elementSize; return self; } -- (void)dealloc { - [_data release]; - [super dealloc]; -} - - (BOOL)isEqual:(id)object { if (self == object) { return YES; @@ -220,15 +205,10 @@ @implementation FlutterStandardWriter { - (instancetype)initWithData:(NSMutableData*)data { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _data = [data retain]; + _data = data; return self; } -- (void)dealloc { - [_data release]; - [super dealloc]; -} - - (void)writeByte:(UInt8)value { [_data appendBytes:&value length:1]; } @@ -273,7 +253,7 @@ - (void)writeValue:(id)value { if (value == nil || value == [NSNull null]) { [self writeByte:FlutterStandardFieldNil]; } else if ([value isKindOfClass:[NSNumber class]]) { - CFNumberRef number = (CFNumberRef)value; + CFNumberRef number = (__bridge CFNumberRef)value; BOOL success = NO; if (CFGetTypeID(number) == CFBooleanGetTypeID()) { BOOL b = CFBooleanGetValue((CFBooleanRef)number); @@ -348,16 +328,11 @@ @implementation FlutterStandardReader { - (instancetype)initWithData:(NSData*)data { self = [super init]; NSAssert(self, @"Super init cannot be nil"); - _data = [data retain]; + _data = [data copy]; _range = NSMakeRange(0, 0); return self; } -- (void)dealloc { - [_data release]; - [super dealloc]; -} - - (BOOL)hasMore { return _range.location < _data.length; } @@ -398,7 +373,7 @@ - (NSData*)readData:(NSUInteger)length { - (NSString*)readUTF8 { NSData* bytes = [self readData:[self readSize]]; - return [[[NSString alloc] initWithData:bytes encoding:NSUTF8StringEncoding] autorelease]; + return [[NSString alloc] initWithData:bytes encoding:NSUTF8StringEncoding]; } - (void)readAlignment:(UInt8)alignment { @@ -482,10 +457,10 @@ - (nullable id)readValueOfType:(UInt8)type { @implementation FlutterStandardReaderWriter - (FlutterStandardWriter*)writerWithData:(NSMutableData*)data { - return [[[FlutterStandardWriter alloc] initWithData:data] autorelease]; + return [[FlutterStandardWriter alloc] initWithData:data]; } - (FlutterStandardReader*)readerWithData:(NSData*)data { - return [[[FlutterStandardReader alloc] initWithData:data] autorelease]; + return [[FlutterStandardReader alloc] initWithData:data]; } @end diff --git a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm index 36de96d451a8d..d61a29e0f31fd 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterRestorationPluginTest.mm @@ -80,7 +80,7 @@ - (void)testRestorationEnabledWaitsForData { [restorationPlugin setRestorationData:data]; XCTAssertEqual([capturedResult count], 2u); XCTAssertEqual([capturedResult objectForKey:@"enabled"], @YES); - XCTAssertEqual([[capturedResult objectForKey:@"data"] data], data); + XCTAssertEqualObjects([[capturedResult objectForKey:@"data"] data], data); } - (void)testRestorationDisabledRespondsRightAway { @@ -112,7 +112,7 @@ - (void)testRespondsRightAwayWhenDataIsSet { }]; XCTAssertEqual([capturedResult count], 2u); XCTAssertEqual([capturedResult objectForKey:@"enabled"], @YES); - XCTAssertEqual([[capturedResult objectForKey:@"data"] data], data); + XCTAssertEqualObjects([[capturedResult objectForKey:@"data"] data], data); } - (void)testRespondsWithNoDataWhenRestorationIsCompletedWithoutData { @@ -161,7 +161,7 @@ - (void)testReturnsDataSetByFramework { result:^(id _Nullable result) { XCTAssertNil(result); }]; - XCTAssertEqual([restorationPlugin restorationData], data); + XCTAssertEqualObjects([restorationPlugin restorationData], data); } - (void)testRespondsWithDataSetByFramework { @@ -177,7 +177,7 @@ - (void)testRespondsWithDataSetByFramework { result:^(id _Nullable result) { XCTAssertNil(result); }]; - XCTAssertEqual([restorationPlugin restorationData], data); + XCTAssertEqualObjects([restorationPlugin restorationData], data); __block id capturedResult; methodCall = [FlutterMethodCall methodCallWithMethodName:@"get" arguments:nil]; @@ -187,7 +187,7 @@ - (void)testRespondsWithDataSetByFramework { }]; XCTAssertEqual([capturedResult count], 2u); XCTAssertEqual([capturedResult objectForKey:@"enabled"], @YES); - XCTAssertEqual([[capturedResult objectForKey:@"data"] data], data); + XCTAssertEqualObjects([[capturedResult objectForKey:@"data"] data], data); } - (void)testResetClearsData { @@ -203,7 +203,7 @@ - (void)testResetClearsData { result:^(id _Nullable result) { XCTAssertNil(result); }]; - XCTAssertEqual([restorationPlugin restorationData], data); + XCTAssertEqualObjects([restorationPlugin restorationData], data); [restorationPlugin reset]; XCTAssertNil([restorationPlugin restorationData]);