Skip to content

Commit

Permalink
Migrate FlutterChannelKeyResponder and FlutterSpellCheckPlugin to ARC (
Browse files Browse the repository at this point in the history
…flutter#52148)

Clean up headers in FlutterChannelKeyResponder and FlutterSpellCheckPlugin.  Migrate to ARC.

Move `FlutterSpellCheckResult` interface into the .mm since it's only used there.

Part of flutter/flutter#137801.
Blocked by flutter#51633 `FlutterUIPressProxy`
  • Loading branch information
jmagman authored Apr 16, 2024
1 parent 7c83b12 commit e7d8c62
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 60 deletions.
8 changes: 4 additions & 4 deletions shell/platform/darwin/ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ source_set("flutter_framework_source_arc") {
sources = [
"framework/Source/FlutterCallbackCache.mm",
"framework/Source/FlutterCallbackCache_Internal.h",
"framework/Source/FlutterChannelKeyResponder.h",
"framework/Source/FlutterChannelKeyResponder.mm",
"framework/Source/FlutterDartVMServicePublisher.h",
"framework/Source/FlutterDartVMServicePublisher.mm",
"framework/Source/FlutterEmbedderKeyResponder.h",
Expand All @@ -73,6 +75,8 @@ source_set("flutter_framework_source_arc") {
"framework/Source/FlutterMetalLayer.mm",
"framework/Source/FlutterRestorationPlugin.h",
"framework/Source/FlutterRestorationPlugin.mm",
"framework/Source/FlutterSpellCheckPlugin.h",
"framework/Source/FlutterSpellCheckPlugin.mm",
"framework/Source/FlutterTextInputDelegate.h",
"framework/Source/FlutterTextInputPlugin.h",
"framework/Source/FlutterTextInputPlugin.mm",
Expand Down Expand Up @@ -137,8 +141,6 @@ source_set("flutter_framework_source") {
# New files are highly encouraged to be in ARC.
# To add new files in ARC, add them to the `flutter_framework_source_arc` target.
"framework/Source/FlutterAppDelegate.mm",
"framework/Source/FlutterChannelKeyResponder.h",
"framework/Source/FlutterChannelKeyResponder.mm",
"framework/Source/FlutterDartProject.mm",
"framework/Source/FlutterDartProject_Internal.h",
"framework/Source/FlutterEngine.mm",
Expand All @@ -155,8 +157,6 @@ source_set("flutter_framework_source") {
"framework/Source/FlutterPluginAppLifeCycleDelegate.mm",
"framework/Source/FlutterSemanticsScrollView.h",
"framework/Source/FlutterSemanticsScrollView.mm",
"framework/Source/FlutterSpellCheckPlugin.h",
"framework/Source/FlutterSpellCheckPlugin.mm",
"framework/Source/FlutterUndoManagerDelegate.h",
"framework/Source/FlutterUndoManagerPlugin.h",
"framework/Source/FlutterUndoManagerPlugin.mm",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@

#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterChannelKeyResponder.h"

#import <objc/message.h>
#include <sys/types.h>
#include "fml/memory/weak_ptr.h"

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterUIPressProxy.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/KeyCodeMap_Internal.h"

FLUTTER_ASSERT_ARC

namespace {
// An enumeration of the modifier values that the framework expects. These are
// largely the same values as the OS (UIKeyModifierShift, etc.), but because the
Expand Down Expand Up @@ -139,7 +135,7 @@ - (void)handlePress:(nonnull FlutterUIPressProxy*)press
NSString* characters = getEventCharacters(press.key.characters, press.key.keyCode);
NSString* charactersIgnoringModifiers =
getEventCharacters(press.key.charactersIgnoringModifiers, press.key.keyCode);
NSMutableDictionary* keyMessage = [[@{
NSDictionary* keyMessage = @{
@"keymap" : @"ios",
@"type" : type,
@"keyCode" : @(press.key.keyCode),
Expand All @@ -148,7 +144,7 @@ - (void)handlePress:(nonnull FlutterUIPressProxy*)press
@"charactersIgnoringModifiers" : charactersIgnoringModifiers == nil
? @""
: charactersIgnoringModifiers,
} mutableCopy] autorelease];
};
[self.channel sendMessage:keyMessage
reply:^(id reply) {
bool handled = reply ? [[reply valueForKey:@"handled"] boolValue] : true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,13 @@
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERSPELLCHECKPLUGIN_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERSPELLCHECKPLUGIN_H_

#include "flutter/fml/memory/weak_ptr.h"

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h"
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"

@interface FlutterSpellCheckPlugin : NSObject

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;

@end

@interface FlutterSpellCheckResult : NSObject

@property(nonatomic, copy, readonly) NSArray<NSString*>* suggestions;
@property(nonatomic, assign, readonly) NSRange misspelledRange;

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)initWithMisspelledRange:(NSRange)range
suggestions:(NSArray<NSString*>*)suggestions NS_DESIGNATED_INITIALIZER;
- (NSDictionary<NSString*, NSObject*>*)toDictionary;

@end

#endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERSPELLCHECKPLUGIN_H_
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,39 @@
#import <UIKit/UIKit.h>

#import "flutter/fml/logging.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"

FLUTTER_ASSERT_ARC

// Method Channel name to start spell check.
static NSString* const kInitiateSpellCheck = @"SpellCheck.initiateSpellCheck";

@interface FlutterSpellCheckResult : NSObject

@property(nonatomic, copy, readonly) NSArray<NSString*>* suggestions;
@property(nonatomic, assign, readonly) NSRange misspelledRange;

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)initWithMisspelledRange:(NSRange)range
suggestions:(NSArray<NSString*>*)suggestions NS_DESIGNATED_INITIALIZER;
- (NSDictionary<NSString*, NSObject*>*)toDictionary;

@end

@interface FlutterSpellCheckPlugin ()

@property(nonatomic, retain) UITextChecker* textChecker;
@property(nonatomic) UITextChecker* textChecker;

@end

@implementation FlutterSpellCheckPlugin

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if (!_textChecker) {
if (!self.textChecker) {
// UITextChecker is an expensive object to initiate, see:
// https://github.com/flutter/flutter/issues/104454. Lazily initialate the UITextChecker object
// until at first method channel call. We avoid using lazy getter for testing.
_textChecker = [[UITextChecker alloc] init];
self.textChecker = [[UITextChecker alloc] init];
}
NSString* method = call.method;
NSArray* args = call.arguments;
Expand Down Expand Up @@ -88,13 +102,13 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
}
} while (nextSpellSuggestion != nil && nextOffset < text.length);

NSMutableArray* methodChannelResult = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray* methodChannelResult =
[[NSMutableArray alloc] initWithCapacity:allSpellSuggestions.count];

for (FlutterSpellCheckResult* result in allSpellSuggestions) {
[methodChannelResult addObject:[result toDictionary]];
}

[allSpellSuggestions release];
return methodChannelResult;
}

Expand All @@ -121,19 +135,8 @@ - (FlutterSpellCheckResult*)findSpellCheckSuggestionsForText:(NSString*)text
NSArray<NSString*>* suggestions = [self.textChecker guessesForWordRange:misspelledRange
inString:text
language:language];
FlutterSpellCheckResult* result =
[[[FlutterSpellCheckResult alloc] initWithMisspelledRange:misspelledRange
suggestions:suggestions] autorelease];
return result;
}

- (UITextChecker*)textChecker {
return _textChecker;
}

- (void)dealloc {
[_textChecker release];
[super dealloc];
return [[FlutterSpellCheckResult alloc] initWithMisspelledRange:misspelledRange
suggestions:suggestions];
}

@end
Expand All @@ -151,18 +154,14 @@ - (instancetype)initWithMisspelledRange:(NSRange)range
}

- (NSDictionary<NSString*, NSObject*>*)toDictionary {
NSMutableDictionary* result = [[[NSMutableDictionary alloc] initWithCapacity:3] autorelease];
result[@"startIndex"] = @(_misspelledRange.location);
// The end index represents the next index after the last character of a misspelled word to match
// the behavior of Dart's TextRange: https://api.flutter.dev/flutter/dart-ui/TextRange/end.html
result[@"endIndex"] = @(_misspelledRange.location + _misspelledRange.length);
result[@"suggestions"] = _suggestions;
return result;
}

- (void)dealloc {
[_suggestions release];
[super dealloc];
return @{
@"startIndex" : @(_misspelledRange.location),
// The end index represents the next index after the last character of a misspelled word to
// match the behavior of Dart's TextRange:
// https://api.flutter.dev/flutter/dart-ui/TextRange/end.html
@"endIndex" : @(_misspelledRange.location + _misspelledRange.length),
@"suggestions" : _suggestions,
};
}

@end

0 comments on commit e7d8c62

Please sign in to comment.