This commit is contained in:
2024-11-17 16:01:34 +08:00
commit 7d68ed0f6c
250 changed files with 8930 additions and 0 deletions

View File

@ -0,0 +1,12 @@
//
// Created by Yohom Bao on 2019/11/29.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void CGPointHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,98 @@
//
// Created by Yohom Bao on 2019/11/29.
//
#import <Flutter/Flutter.h>
#import "CGPointHandler.h"
extern BOOL enableLog;
void CGPointHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"CGPoint::getX" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *value = (NSValue *) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
CGPoint cgPoint = value.CGPointValue;
methodResult(@(cgPoint.x));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGPoint::getY" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *value = (NSValue *) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
CGPoint cgPoint = value.CGPointValue;
methodResult(@(cgPoint.y));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGPoint::getX_batch" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSArray<NSValue*>* value = (NSArray<NSValue*>*) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
NSMutableArray<NSNumber*>* result = [NSMutableArray arrayWithCapacity:value.count];
for (NSValue* pointValue in value) {
[result addObject:@(pointValue.CGPointValue.x)];
}
methodResult(result);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGPoint::getY_batch" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSArray<NSValue*>* value = (NSArray<NSValue*>*) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
NSMutableArray<NSNumber*>* result = [NSMutableArray arrayWithCapacity:value.count];
for (NSValue* pointValue in value) {
[result addObject:@(pointValue.CGPointValue.y)];
}
methodResult(result);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGPoint::create" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSNumber *x = (NSNumber *) args[@"x"];
NSNumber *y = (NSNumber *) args[@"y"];
CGPoint cgPoint = CGPointMake([x floatValue], [y floatValue]);
NSValue *valuePoint = [NSValue valueWithCGPoint:cgPoint];
methodResult(valuePoint);
} else if ([@"CGPoint::create_batch" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSArray<NSNumber*>* x = (NSArray<NSNumber*>*) args[@"x"];
NSArray<NSNumber*>* y = (NSArray<NSNumber*>*) args[@"y"];
NSMutableArray<NSValue*>* result = [NSMutableArray arrayWithCapacity:x.count];
for (NSUInteger i = 0; i < x.count; i++) {
CGPoint cgPoint = CGPointMake([x[i] floatValue], [y[i] floatValue]);
NSValue *valuePoint = [NSValue valueWithCGPoint:cgPoint];
[result addObject:valuePoint];
}
methodResult(result);
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// CGRectHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/4/20.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void CGRectHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,78 @@
//
// CGRectHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/4/20.
//
#import "CGRectHandler.h"
extern BOOL enableLog;
void CGRectHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"CGRect::create" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
CGFloat x = [(NSNumber*) args[@"x"] floatValue];
CGFloat y = [(NSNumber*) args[@"y"] floatValue];
CGFloat width = [(NSNumber*) args[@"width"] floatValue];
CGFloat height = [(NSNumber*) args[@"height"] floatValue];
CGRect rect = CGRectMake(x, y, width, height);
NSValue* result = [NSValue valueWithCGRect:rect];
methodResult(result);
} else if ([@"CGRect::getX" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *value = (NSValue *) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
CGRect cgRect = value.CGRectValue;
methodResult(@(cgRect.origin.x));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGRect::getY" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *value = (NSValue *) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
CGRect cgRect = value.CGRectValue;
methodResult(@(cgRect.origin.y));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGRect::getWidth" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *value = (NSValue *) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
CGRect cgRect = value.CGRectValue;
methodResult(@(cgRect.size.width));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGRect::getHeight" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *value = (NSValue *) args[@"__this__"];
if (value != nil && (NSNull*) value != [NSNull null]) {
CGRect cgRect = value.CGRectValue;
methodResult(@(cgRect.size.height));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// CGSizeHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/6/22.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void CGSizeHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,52 @@
//
// CGSizeHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/6/22.
//
#import "CGSizeHandler.h"
extern BOOL enableLog;
void CGSizeHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"CGSize::create" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
CGFloat width = [(NSNumber*) args[@"width"] floatValue];
CGFloat height = [(NSNumber*) args[@"height"] floatValue];
CGSize rect = CGSizeMake(width, height);
NSValue* result = [NSValue valueWithCGSize:rect];
methodResult(result);
} else if ([@"CGSize::getWidth" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *__this__ = (NSValue *) args[@"__this__"];
if (__this__ != nil && (NSNull*) __this__ != [NSNull null]) {
CGSize cgSize = __this__.CGSizeValue;
methodResult(@(cgSize.width));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"CGSize::getHeight" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *__this__ = (NSValue *) args[@"__this__"];
if (__this__ != nil && (NSNull*) __this__ != [NSNull null]) {
CGSize cgSize = __this__.CGSizeValue;
methodResult(@(cgSize.height));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,24 @@
//
// FluttifyMessageCodec.h
// FMDB
//
// Created by Yohom Bao on 2020/8/31.
//
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface FluttifyReaderWriter : FlutterStandardReaderWriter
@end
@interface FluttifyWriter : FlutterStandardWriter
@end
@interface FluttifyReader : FlutterStandardReader
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,230 @@
//
// FluttifyMessageCodec.m
// FMDB
//
// Created by Yohom Bao on 2020/8/31.
//
#import "FluttifyMessageCodec.h"
extern NSMutableDictionary<NSString *, NSObject *> *HEAP;
typedef NS_ENUM(NSInteger, FluttifyField) {
FluttifyFieldNil,
FluttifyFieldTrue,
FluttifyFieldFalse,
FluttifyFieldInt32,
FluttifyFieldInt64,
FluttifyFieldIntHex,
FluttifyFieldFloat64,
FluttifyFieldString,
// The following must match the corresponding order from `FlutterStandardDataType`.
FluttifyFieldUInt8Data,
FluttifyFieldInt32Data,
FluttifyFieldInt64Data,
FluttifyFieldFloat64Data,
FluttifyFieldList,
FluttifyFieldMap,
FluttifyFieldEnum = 126,
FluttifyFieldRef = 127,
};
UInt8 elementSizeForFlutterStandardDataType(FlutterStandardDataType type) {
switch (type) {
case FlutterStandardDataTypeUInt8:
return 1;
case FlutterStandardDataTypeInt32:
return 4;
case FlutterStandardDataTypeInt64:
return 8;
case FlutterStandardDataTypeFloat64:
return 8;
default:
return 0;
}
}
@implementation FluttifyReaderWriter
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
return [[FluttifyWriter alloc] initWithData:data];
}
- (FlutterStandardReader *)readerWithData:(NSData *)data {
return [[FluttifyReader alloc] initWithData:data];
}
@end
@implementation FluttifyWriter
- (void)writeValue:(id)value {
if (value == nil || value == [NSNull null]) {
[self writeByte:FluttifyFieldNil];
} else if ([value isKindOfClass:[NSNumber class]]) {
CFNumberRef number = (__bridge CFNumberRef) value;
BOOL success = NO;
if (CFGetTypeID(number) == CFBooleanGetTypeID()) {
BOOL b = CFBooleanGetValue((CFBooleanRef) number);
[self writeByte:(b ? FluttifyFieldTrue : FluttifyFieldFalse)];
success = YES;
} else if (CFNumberIsFloatType(number)) {
Float64 f;
success = CFNumberGetValue(number, kCFNumberFloat64Type, &f);
if (success) {
[self writeByte:FluttifyFieldFloat64];
[self writeAlignment:8];
[self writeBytes:(UInt8 *) &f length:8];
}
} else if (CFNumberGetByteSize(number) <= 4) {
SInt32 n;
success = CFNumberGetValue(number, kCFNumberSInt32Type, &n);
if (success) {
[self writeByte:FluttifyFieldInt32];
[self writeBytes:(UInt8 *) &n length:4];
}
} else if (CFNumberGetByteSize(number) <= 8) {
SInt64 n;
success = CFNumberGetValue(number, kCFNumberSInt64Type, &n);
if (success) {
[self writeByte:FluttifyFieldInt64];
[self writeBytes:(UInt8 *) &n length:8];
}
}
if (!success) {
NSLog(@"Unsupported value: %@ of number type %d", value, CFNumberGetType(number));
NSAssert(NO, @"Unsupported value for standard codec");
}
} else if ([value isKindOfClass:[NSString class]]) {
NSString *string = value;
[self writeByte:FluttifyFieldString];
[self writeUTF8:string];
} else if ([value isKindOfClass:[FlutterStandardTypedData class]]) {
FlutterStandardTypedData *typedData = value;
[self writeByte:(FluttifyField) (typedData.type + FluttifyFieldUInt8Data)];
[self writeSize:typedData.elementCount];
[self writeAlignment:typedData.elementSize];
[self writeData:typedData.data];
}
// NSData, fluttifyNSData, NSData
/*else if ([value isKindOfClass:[NSData class]]) {
[self writeValue:[FlutterStandardTypedData typedDataWithBytes:value]];
} */
else if ([value isKindOfClass:[NSArray class]]) {
NSArray *array = value;
[self writeByte:FluttifyFieldList];
[self writeSize:array.count];
for (id object in array) {
[self writeValue:object];
}
} else if ([value isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = value;
[self writeByte:FluttifyFieldMap];
[self writeSize:dict.count];
for (id key in dict) {
[self writeValue:key];
[self writeValue:dict[key]];
}
}
// NSObject
else if ([value isKindOfClass:[NSObject class]]) {
NSUInteger hash = [value hash];
NSString* refId = [NSString stringWithFormat:@"%@:%@", NSStringFromClass([value class]), @(hash)];
[self writeByte:FluttifyFieldRef];
[self writeUTF8:refId];
HEAP[refId] = value;
} else {
NSLog(@"Unsupported value: %@ of type %@", value, [value class]);
NSAssert(NO, @"Unsupported value for standard codec");
}
}
@end
@implementation FluttifyReader
- (FlutterStandardTypedData *)readTypedDataOfType:(FlutterStandardDataType)type {
UInt32 elementCount = [self readSize];
UInt8 elementSize = elementSizeForFlutterStandardDataType(type);
[self readAlignment:elementSize];
NSData *data = [self readData:elementCount * elementSize];
switch (type) {
case FlutterStandardDataTypeUInt8:
return [FlutterStandardTypedData typedDataWithBytes:data];
case FlutterStandardDataTypeInt32:
return [FlutterStandardTypedData typedDataWithInt32:data];
case FlutterStandardDataTypeInt64:
return [FlutterStandardTypedData typedDataWithInt64:data];
case FlutterStandardDataTypeFloat64:
return [FlutterStandardTypedData typedDataWithFloat64:data];
default:
return nil;
}
}
- (nullable id)readValueOfType:(UInt8)type {
FluttifyField field = (FluttifyField) type;
switch (field) {
case FluttifyFieldNil:
return nil;
case FluttifyFieldTrue:
return @YES;
case FluttifyFieldFalse:
return @NO;
case FluttifyFieldInt32: {
SInt32 value;
[self readBytes:&value length:4];
return @(value);
}
case FluttifyFieldInt64: {
SInt64 value;
[self readBytes:&value length:8];
return @(value);
}
case FluttifyFieldFloat64: {
Float64 value;
[self readAlignment:8];
[self readBytes:&value length:8];
return @(value);
}
case FluttifyFieldIntHex:
case FluttifyFieldString:
return [self readUTF8];
case FluttifyFieldUInt8Data:
case FluttifyFieldInt32Data:
case FluttifyFieldInt64Data:
case FluttifyFieldFloat64Data:
return [self readTypedDataOfType:(FlutterStandardDataType) (field - FluttifyFieldUInt8Data)];
case FluttifyFieldList: {
UInt32 length = [self readSize];
NSMutableArray *array = [NSMutableArray arrayWithCapacity:length];
for (UInt32 i = 0; i < length; i++) {
id value = [self readValue];
[array addObject:(value == nil ? [NSNull null] : value)];
}
return array;
}
case FluttifyFieldMap: {
UInt32 size = [self readSize];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:size];
for (UInt32 i = 0; i < size; i++) {
id key = [self readValue];
id val = [self readValue];
dict[key == nil ? [NSNull null] : key] = val == nil ? [NSNull null] : val;
}
return dict;
}
// 使int
case FluttifyFieldEnum: {
SInt32 value;
[self readBytes:&value length:4];
return @(value);
}
case FluttifyFieldRef: {
NSString *refId = [self readUTF8];
return HEAP[refId];
}
default:
NSAssert(NO, @"Corrupted standard message");
return nil;
}
}
@end

View File

@ -0,0 +1,9 @@
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface FoundationFluttifyPlugin : NSObject<FlutterPlugin>
- (instancetype) initWithRegistrar:(NSObject<FlutterPluginRegistrar>*) registrar;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,410 @@
#import "FoundationFluttifyPlugin.h"
#import "PlatformService.h"
#import "UIImageHandler.h"
#import "UIViewHandler.h"
#import "CGPointHandler.h"
#import "NSDataHandler.h"
#import "NSDateHandler.h"
#import "UIEdgeInsetsHandler.h"
#import "UIColorHandler.h"
#import "NSErrorHandler.h"
#import "CGRectHandler.h"
#import "CGSizeHandler.h"
#import "UIViewControllerHandler.h"
#import "UIImageViewHandler.h"
#import "NSObjectHandler.h"
#import "platform_view/UIViewFactory.h"
#import "FluttifyMessageCodec.h"
// The stack that exists on the Dart side for a method call is enabled only when the MethodChannel passing parameters are limited
NSMutableDictionary<NSString *, NSObject *> *STACK;
// Container for Dart side random access objects
NSMutableDictionary<NSString *, NSObject *> *HEAP;
// whether enable log or not
BOOL enableLog;
NSString *_channelName = @"com.fluttify/foundation_method";
@implementation FoundationFluttifyPlugin {
NSObject <FlutterPluginRegistrar> *_registrar;
}
+ (void)registerWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar {
//
STACK = @{}.mutableCopy;
//
HEAP = @{}.mutableCopy;
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
FoundationFluttifyPlugin *instance = [[FoundationFluttifyPlugin alloc] initWithRegistrar:registrar];
[registrar addMethodCallDelegate:instance channel:channel];
[registrar registerViewFactory:[[UIViewFactory alloc] initWithRegistrar:registrar] withId:@"me.yohom/foundation_fluttify/UIView"];
}
- (instancetype)initWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_registrar = registrar;
[_registrar addApplicationDelegate:self];
}
return self;
}
- (void)handleMethodCall:(FlutterMethodCall *)methodCall result:(FlutterResult)methodResult {
id rawArgs = [methodCall arguments];
if ([methodCall.method hasPrefix:@"UIImage::"]) {
UIImageHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"UIViewController::"]) {
UIViewControllerHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"UIView::"]) {
UIViewHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"CGPoint::"]) {
CGPointHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"NSData::"]) {
NSDataHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"UIEdgeInsets::"]) {
UIEdgeInsetsHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"UIColor::"]) {
UIColorHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"NSError::"]) {
NSErrorHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"CGRect::"]) {
CGRectHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"CGSize::"]) {
CGSizeHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"UIImageView::"]) {
UIImageViewHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"NSObject::"]) {
NSObjectHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"NSDate::"]) {
NSDateHandler(methodCall.method, rawArgs, methodResult);
} else if ([methodCall.method hasPrefix:@"Platform"]) {
PlatformService(methodCall.method, rawArgs, methodResult, self->_registrar);
} else {
methodResult(FlutterMethodNotImplemented);
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (enableLog) {
NSLog(@"application:didFinishLaunchingWithOptions");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationDidFinishLaunchingWithOptions"
arguments:@{@"application": application, @"launchOptions": @{}}]; // NSDictionary,
return YES;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `NO` if this vetoes application launch.
*/
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (enableLog) {
NSLog(@"application:willFinishLaunchingWithOptions");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationWillFinishLaunchingWithOptions"
arguments:@{@"application": application, @"launchOptions": @{}}];
return YES;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationDidBecomeActive:(UIApplication *)application {
if (enableLog) {
NSLog(@"applicationDidBecomeActive");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationDidBecomeActive"
arguments:@{@"application": application}];
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillResignActive:(UIApplication *)application {
if (enableLog) {
NSLog(@"applicationWillResignActive");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationWillResignActive"
arguments:@{@"application": application}];
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationDidEnterBackground:(UIApplication *)application {
if (enableLog) {
NSLog(@"applicationDidEnterBackground");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationDidEnterBackground"
arguments:@{@"application": application}];
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillEnterForeground:(UIApplication *)application {
if (enableLog) {
NSLog(@"applicationWillEnterForeground");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationWillEnterForeground"
arguments:@{@"application": application}];
}
/**
Called if this has been registered for `UIApplicationDelegate` callbacks.
*/
- (void)applicationWillTerminate:(UIApplication *)application {
if (enableLog) {
NSLog(@"applicationWillTerminate");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationWillTerminate"
arguments:@{@"application": application}];
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*/
- (void) application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
API_DEPRECATED(
"See -[UIApplicationDelegate application:didRegisterUserNotificationSettings:] deprecation",
ios(8.0, 10.0)) {
if (enableLog) {
NSLog(@"application:didRegisterUserNotificationSettings");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationDidRegisterUserNotificationSettings"
arguments:@{@"application": application, @"notificationSettings": notificationSettings}];
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*/
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
if (enableLog) {
NSLog(@"application:didRegisterForRemoteNotificationsWithDeviceToken");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationDidRegisterForRemoteNotificationsWithDeviceToken"
arguments:@{@"application": application, @"deviceToken": deviceToken}];
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL) application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
if (enableLog) {
NSLog(@"application:didReceiveRemoteNotification:fetchCompletionHandler");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationDidReceiveRemoteNotificationFetchCompletionHandler"
arguments:@{@"application": application, @"userInfo": userInfo}];
return NO;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
if (enableLog) {
NSLog(@"application:openURL:options");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationOpenURLOptions"
arguments:@{@"application": application, @"url": url, @"options": @{}}];
return NO;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
if (enableLog) {
NSLog(@"application:handleOpenURL");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationHandleOpenURL"
arguments:@{@"application": application, @"url": url}];
return NO;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if (enableLog) {
NSLog(@"application:openURL:sourceApplication:annotation");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationOpenURLSourceApplicationAnnotation"
arguments:@{@"application": application, @"url": url, @"sourceApplication": sourceApplication, @"annotation": (NSObject *) annotation}];
return NO;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL) application:(UIApplication *)application
performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
completionHandler:(void (^)(BOOL succeeded))completionHandler
API_AVAILABLE(ios(9.0)) {
if (enableLog) {
NSLog(@"application:performActionForShortcutItem:completionHandler");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationPerformActionForShortcutItemCompletionHandler"
arguments:@{@"application": application, @"shortcutItem": shortcutItem}];
return NO;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL) application:(UIApplication *)application
handleEventsForBackgroundURLSession:(nonnull NSString *)identifier
completionHandler:(nonnull void (^)(void))completionHandler {
if (enableLog) {
NSLog(@"application:handleEventsForBackgroundURLSession:completionHandler");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationHandleEventsForBackgroundURLSessionCompletionHandler"
arguments:@{@"application": application, @"identifier": identifier}];
return NO;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL) application:(UIApplication *)application
performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
if (enableLog) {
NSLog(@"application:performFetchWithCompletionHandler");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationPerformFetchWithCompletionHandler"
arguments:@{@"application": application}];
return NO;
}
/**
* Called if this has been registered for `UIApplicationDelegate` callbacks.
*
* @return `YES` if this handles the request.
*/
- (BOOL) application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *))restorationHandler {
if (enableLog) {
NSLog(@"application:continueUserActivity:restorationHandler");
}
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:_channelName
binaryMessenger:[_registrar messenger]
codec:[FlutterStandardMethodCodec codecWithReaderWriter:[[FluttifyReaderWriter alloc] init]]];
[channel invokeMethod:@"applicationContinueUserActivityRestorationHandler"
arguments:@{@"application": application, @"userActivity": userActivity}];
return NO;
}
@end

View File

@ -0,0 +1,12 @@
//
// Created by Yohom Bao on 2019/11/25.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void NSDataHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,36 @@
//
// Created by Yohom Bao on 2019/11/25.
//
#import "NSDataHandler.h"
extern BOOL enableLog;
void NSDataHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"NSData::createWithUint8List" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
FlutterStandardTypedData *data = (FlutterStandardTypedData *) args[@"data"];
if (data != nil && (NSNull*) data != [NSNull null]) {
NSData *target = data.data;
methodResult(target);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"NSData::getData" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSData *target = (NSData *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
methodResult([FlutterStandardTypedData typedDataWithBytes:target]);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// NSDateHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/11/9.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void NSDateHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,27 @@
//
// NSDateHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/11/9.
//
#import "NSDateHandler.h"
extern BOOL enableLog;
void NSDateHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"NSDate::get_timeIntervalSince1970" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSDate *target = (NSDate *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
methodResult(@(target.timeIntervalSince1970));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// NSErrorHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/4/5.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void NSErrorHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,39 @@
//
// NSErrorHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/4/5.
//
#import "NSErrorHandler.h"
extern BOOL enableLog;
void NSErrorHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"NSError::getCode" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSError *target = (NSError *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
methodResult(@(target.code));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"NSError::getDescription" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSError *target = (NSError *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
methodResult(target.description);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// NSObjectHandler.h
// FMDB
//
// Created by Yohom Bao on 2020/9/14.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void NSObjectHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,32 @@
//
// NSObjectHandler.m
// FMDB
//
// Created by Yohom Bao on 2020/9/14.
//
#import "NSObjectHandler.h"
extern BOOL enableLog;
void NSObjectHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"NSObject::init" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSObject *__this__ = (NSObject *) args[@"__this__"];
NSObject *target = [__this__ init];
methodResult(target);
} else if ([@"NSObject::init_batch" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSObject *__this__ = (NSObject *) args[@"__this__"];
NSObject *target = [__this__ init];
methodResult(target);
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// PlatformFactoryHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2019/11/22.
//
#import "FoundationFluttifyPlugin.h"
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void PlatformService(NSString* method, id args, FlutterResult methodResult, NSObject<FlutterPluginRegistrar>* registrar);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,352 @@
//
// PlatformFactoryHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2019/11/22.
//
#import "PlatformService.h"
#import <CoreLocation/CoreLocation.h>
#import <objc/runtime.h>
extern NSMutableDictionary<NSString *, NSObject *> *STACK;
extern NSMutableDictionary<NSString *, NSObject *> *HEAP;
extern BOOL enableLog;
void PlatformService(NSString* method, id rawArgs, FlutterResult methodResult, NSObject<FlutterPluginRegistrar>* registrar) {
// toggle log
if ([@"PlatformService::enableLog" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
enableLog = [args[@"enable"] boolValue];
methodResult(@"success");
}
//
else if ([@"PlatformService::performSelectorWithObject" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSString *selector = (NSString *) args[@"selector"];
NSObject *object = (NSObject *) args[@"object"];
NSObject *__this__ = (NSObject *) args[@"__this__"];
if (__this__ != nil && (NSNull*) __this__ != [NSNull null]) {
[__this__ performSelector:NSSelectorFromString(selector) withObject:object];
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
}
//
else if ([@"PlatformService::isNull" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSObject *__this__ = (NSObject *) args[@"__this__"];
methodResult(@(__this__ == nil || (NSNull*) __this__ == [NSNull null]));
}
//
else if ([@"PlatformService::addProperty" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *property__ = (NSObject *) args[@"property"];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
objc_setAssociatedObject(__this__, (const void *) propertyKey, property__, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
}
}
//
else if ([@"PlatformService::addListProperty" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSArray<NSObject*>* property__ = (NSArray<NSObject *>*) args[@"property"];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
objc_setAssociatedObject(__this__, (const void *) propertyKey, property__, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
}
}
//
else if ([@"PlatformService::addProperty_batch" isEqualToString:method]) {
NSArray<NSDictionary<NSString*, NSObject*>*>* argsBatch = (NSArray<NSDictionary<NSString*, NSObject*>*>*) rawArgs;
NSMutableArray* resultList = [NSMutableArray array];
for (NSUInteger __i__ = 0; __i__ < argsBatch.count; __i__++) {
NSDictionary<NSString*, id>* args = argsBatch[__i__];
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *property__ = (NSObject *) args[@"property"];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
objc_setAssociatedObject(__this__, (const void *) propertyKey, property__, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[resultList addObject:@"success"];
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
break;
}
}
methodResult(resultList);
}
//
else if ([@"PlatformService::getProperty" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
NSObject *result = objc_getAssociatedObject(__this__, (const void *) propertyKey);
methodResult(result);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
}
}
//
else if ([@"PlatformService::getProperty_batch" isEqualToString:method]) {
NSArray<NSDictionary<NSString*, NSObject*>*>* argsBatch = (NSArray<NSDictionary<NSString*, NSObject*>*>*) rawArgs;
NSMutableArray* resultList = [NSMutableArray array];
for (NSUInteger __i__ = 0; __i__ < argsBatch.count; __i__++) {
NSDictionary<NSString*, id>* args = argsBatch[__i__];
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
NSObject *result = objc_getAssociatedObject(__this__, (const void *) propertyKey);
[resultList addObject:result];
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
break;
}
}
methodResult(resultList);
}
// jsonable
else if ([@"PlatformService::addJsonableProperty" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *property = (NSObject *) args[@"property"];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
objc_setAssociatedObject(__this__, (const void *) propertyKey, property, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
}
}
// jsonable
else if ([@"PlatformService::addJsonableProperty_batch" isEqualToString:method]) {
NSArray<NSDictionary<NSString*, NSObject*>*>* argsBatch = (NSArray<NSDictionary<NSString*, NSObject*>*>*) rawArgs;
NSMutableArray* resultList = [NSMutableArray array];
for (NSUInteger __i__ = 0; __i__ < argsBatch.count; __i__++) {
NSDictionary<NSString*, id>* args = argsBatch[__i__];
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *property = (NSObject *) args[@"property"];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
objc_setAssociatedObject(__this__, (const void *) propertyKey, property, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[resultList addObject:@"success"];
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
break;
}
}
methodResult(resultList);
}
// jsonable
else if ([@"PlatformService::getJsonableProperty" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
methodResult(objc_getAssociatedObject(__this__, (const void *) propertyKey));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
}
}
// jsonable
else if ([@"PlatformService::getJsonableProperty_batch" isEqualToString:method]) {
NSArray<NSDictionary<NSString*, NSObject*>*>* argsBatch = (NSArray<NSDictionary<NSString*, NSObject*>*>*) rawArgs;
NSMutableArray* resultList = [NSMutableArray array];
for (NSUInteger __i__ = 0; __i__ < argsBatch.count; __i__++) {
NSDictionary<NSString*, id>* args = argsBatch[__i__];
NSInteger propertyKey = [(NSNumber *) args[@"propertyKey"] integerValue];
NSObject *__this__ = args[@"__this__"];
if (__this__ && (NSNull*) __this__ != [NSNull null]) {
NSObject* result = objc_getAssociatedObject(__this__, (const void *) propertyKey);
[resultList addObject:result];
} else {
methodResult([FlutterError errorWithCode:@"目标对象为空" message:@"目标对象为空" details:@"目标对象为空"]);
break;
}
}
methodResult(resultList);
}
//
else if ([@"PlatformService::release" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSNumber *__this__ = (NSNumber *) args[@"__this__"];
if (enableLog) NSLog(@"PlatformService::释放对象: %@", __this__);
[HEAP removeObjectForKey:[NSString stringWithFormat:@"%@", __this__]];
methodResult(@"success");
if (enableLog) NSLog(@"size: %ld, HEAP: %@", [HEAP count], HEAP);
}
//
else if ([@"PlatformService::release_batch" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSArray<NSNumber *>* __this_batch__ = (NSArray<NSNumber*>*) args[@"__this_batch__"];
if (enableLog) NSLog(@"PlatformService::批量释放对象: %@", __this_batch__);
for (NSNumber* item in __this_batch__) {
[HEAP removeObjectForKey:[NSString stringWithFormat:@"%@", item]];
}
methodResult(@"success");
if (enableLog) NSLog(@"size: %ld, HEAP: %@", [HEAP count], HEAP);
}
//
else if ([@"PlatformService::clearHeap" isEqualToString:method]) {
if (enableLog) NSLog(@"PlatformService::清空堆");
[HEAP removeAllObjects];
methodResult(@"success");
if (enableLog) NSLog(@"size: %ld, HEAP: %@", [HEAP count], HEAP);
}
//
else if ([@"PlatformService::pushStack" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSString *name = (NSString *) args[@"name"];
NSObject *__this__ = (NSObject *) args[@"__this__"];
if (enableLog) NSLog(@"PlatformService::压入栈 %@@%@", NSStringFromClass([args[@"__this__"] class]), __this__);
STACK[name] = __this__;
methodResult(@"success");
if (enableLog) NSLog(@"STACK: %@", STACK);
}
// jsonable
else if ([@"PlatformService::pushStackJsonable" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSString *name = (NSString *) args[@"name"];
NSObject *data = (NSObject *) args[@"data"];
if (enableLog) NSLog(@"PlatformService::压入栈 %@", data);
STACK[name] = data;
methodResult(@"success");
if (enableLog) NSLog(@"STACK: %@", STACK);
}
//
else if ([@"PlatformService::clearStack" isEqualToString:method]) {
if (enableLog) NSLog(@"PlatformService::清空栈");
[STACK removeAllObjects];
methodResult(@"success");
if (enableLog) NSLog(@"STACK: %@", STACK);
}
// ViewController
else if ([@"PlatformService::presentViewController" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
if (enableLog) NSLog(@"PlatformService::打开一个ViewController");
NSString* viewControllerClass = (NSString*) args[@"viewControllerClass"];
BOOL withNavigationController = [(NSNumber*) args[@"withNavigationController"] boolValue];
UIViewController *controller = (UIViewController *) [[NSClassFromString(viewControllerClass) alloc] init];
if (withNavigationController) {
// UINavigationController *naviController = [[UINavigationController alloc] initWithRootViewController:controller];
// UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"关闭" style:UIBarButtonItemStyleDone __this__:nil action:@selector(dismiss)];
// [[controller navigationItem] setLeftBarButtonItem:item];
// [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:naviController animated:YES completion:nil];
} else {
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:controller animated:YES completion:nil];
}
methodResult(@"success");
}
// flutter asset
else if ([@"PlatformService::getAssetPath" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSString *flutterAssetPath = (NSString *) args[@"flutterAssetPath"];
if (enableLog) NSLog(@"PlatformService::Flutter Asset%@", flutterAssetPath);
NSString* key = [registrar lookupKeyForAsset:flutterAssetPath];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];
methodResult(path);
}
// viewIdrefId
else if ([@"PlatformService::viewId2RefId" isEqualToString:method]) {
NSDictionary<NSString*, NSObject*>* args = (NSDictionary<NSString*, NSObject*>*) rawArgs;
NSString *viewId = (NSString *) args[@"viewId"];
if (enableLog) NSLog(@"PlatformService::viewId%@", viewId);
if ([[HEAP allKeys] containsObject:viewId]) {
NSObject* object = HEAP[viewId];
methodResult([NSString stringWithFormat:@"%@", @(object.hash)]);
// viewId
[HEAP removeObjectForKey:viewId];
} else {
methodResult([FlutterError errorWithCode:@"viewId无对应对象" message:@"viewId无对应对象" details:@"viewId无对应对象"]);
}
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// UIColorHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/3/9.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void UIColorHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,29 @@
//
// UIColorHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/3/9.
//
#import "UIColorHandler.h"
extern BOOL enableLog;
void UIColorHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"UIColor::create" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSNumber *colorValue = (NSNumber *) args[@"colorValue"];
CGFloat alpha = (0xff000000 & [colorValue integerValue]) >> 24;
CGFloat red = (0x00ff0000 & [colorValue integerValue]) >> 16;
CGFloat green = (0x0000ff00 & [colorValue integerValue]) >> 8;
CGFloat blue = (0x000000ff & [colorValue integerValue]) >> 0;
UIColor *color = [UIColor colorWithRed:red / 0xFF green:green / 0xFF blue:blue / 0xFF alpha:alpha / 0xFF];
methodResult(color);
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,12 @@
//
// Created by Yohom Bao on 2019/12/5.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void UIEdgeInsetsHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,74 @@
//
// Created by Yohom Bao on 2019/12/5.
//
#import "UIEdgeInsetsHandler.h"
extern BOOL enableLog;
void UIEdgeInsetsHandler(NSString* method, id rawArgs, FlutterResult methodResult) {
if ([@"UIEdgeInsets::getTop" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *target = (NSValue *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
UIEdgeInsets insets = [target UIEdgeInsetsValue];
methodResult(@(insets.top));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIEdgeInsets::getLeft" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *target = (NSValue *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
UIEdgeInsets insets = [target UIEdgeInsetsValue];
methodResult(@(insets.left));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIEdgeInsets::getBottom" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *target = (NSValue *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
UIEdgeInsets insets = [target UIEdgeInsetsValue];
methodResult(@(insets.bottom));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIEdgeInsets::getRight" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSValue *target = (NSValue *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
UIEdgeInsets insets = [target UIEdgeInsetsValue];
methodResult(@(insets.right));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIEdgeInsets::create" isEqualToString:method]) {
NSDictionary<NSString*, id>* args = (NSDictionary<NSString*, id>*) rawArgs;
NSNumber *top = (NSNumber *) args[@"top"];
NSNumber *left = (NSNumber *) args[@"left"];
NSNumber *bottom = (NSNumber *) args[@"bottom"];
NSNumber *right = (NSNumber *) args[@"right"];
UIEdgeInsets insets = UIEdgeInsetsMake([top floatValue], [left floatValue], [bottom floatValue], [right floatValue]);
NSValue *valuePoint = [NSValue valueWithUIEdgeInsets:insets];
methodResult(valuePoint);
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,13 @@
//
// Created by Yohom Bao on 2019/11/22.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
#import "FoundationFluttifyPlugin.h"
NS_ASSUME_NONNULL_BEGIN
void UIImageHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,69 @@
//
// Created by Yohom Bao on 2019/11/22.
//
#import "UIImageHandler.h"
extern BOOL enableLog;
void UIImageHandler(NSString *method, id rawArgs, FlutterResult methodResult) {
// UIImage::getData
if ([@"UIImage::getData" isEqualToString:method]) {
NSDictionary<NSString *, id> *args = (NSDictionary<NSString *, id> *) rawArgs;
UIImage *target = (UIImage *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
NSData *data = UIImageJPEGRepresentation(target, 100);
methodResult([FlutterStandardTypedData typedDataWithBytes:data]);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
}
// UIImage
else if ([@"UIImage::createUIImage" isEqualToString:method]) {
NSDictionary<NSString *, id> *args = (NSDictionary<NSString *, id> *) rawArgs;
FlutterStandardTypedData *bitmapBytes = (FlutterStandardTypedData *) args[@"bitmapBytes"];
UIImage *bitmap = [UIImage imageWithData:bitmapBytes.data scale:[UIScreen mainScreen].scale];
methodResult(bitmap);
}
// UIImage
else if ([@"UIImage::createWithPath" isEqualToString:method]) {
NSDictionary<NSString *, id> *args = (NSDictionary<NSString *, id> *) rawArgs;
NSString *resource = (NSString *) args[@"resource"];
NSString *type = (NSString *) args[@"type"];
NSString *fileName = (NSString *) args[@"fileName"];
NSString *path = [[NSBundle mainBundle] pathForResource:resource ofType:type];
path = [path stringByAppendingPathComponent:fileName];
UIImage *bitmap = [UIImage imageWithContentsOfFile:path];
methodResult(bitmap);
}
// UIImage
else if ([@"UIImage::createUIImage_batch" isEqualToString:method]) {
NSArray<NSDictionary<NSString *, NSObject *> *> *argsBatch = (NSArray<NSDictionary<NSString *, NSObject *> *> *) rawArgs;
NSMutableArray<UIImage *> *resultList = [NSMutableArray<UIImage *> array];
for (NSUInteger __i__ = 0; __i__ < argsBatch.count; __i__++) {
NSDictionary<NSString *, id> *args = argsBatch[__i__];
FlutterStandardTypedData *bitmapBytes = (FlutterStandardTypedData *) args[@"bitmapBytes"];
UIImage *bitmap = [UIImage imageWithData:bitmapBytes.data scale:[UIScreen mainScreen].scale];
[resultList addObject:bitmap];
}
methodResult(resultList);
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// UIImageViewHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/7/2.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void UIImageViewHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,24 @@
//
// UIImageViewHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/7/2.
//
#import "UIImageViewHandler.h"
extern BOOL enableLog;
void UIImageViewHandler(NSString *method, id rawArgs, FlutterResult methodResult) {
if ([@"UIImageView::create" isEqualToString:method]) {
NSDictionary<NSString *, id> *args = (NSDictionary<NSString *, id> *) rawArgs;
UIImage *image = (UIImage *) args[@"image"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
methodResult(imageView);
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,15 @@
//
// UIViewControllerHandler.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/6/6.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void UIViewControllerHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,21 @@
//
// UIViewControllerHandler.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/6/6.
//
#import "UIViewControllerHandler.h"
#import <Flutter/Flutter.h>
extern BOOL enableLog;
void UIViewControllerHandler(NSString* method, id args, FlutterResult methodResult) {
if ([@"UIViewController::get" isEqualToString:method]) {
UIViewController* controller = [UIApplication sharedApplication].keyWindow.rootViewController;
methodResult(controller);
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,12 @@
//
// Created by Yohom Bao on 2019/11/22.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
void UIViewHandler(NSString* method, id args, FlutterResult methodResult);
NS_ASSUME_NONNULL_END

210
ios/Classes/UIViewHandler.m Normal file
View File

@ -0,0 +1,210 @@
//
// Created by Yohom Bao on 2019/11/22.
//
#import <Flutter/Flutter.h>
#import "UIViewHandler.h"
extern BOOL enableLog;
void UIViewHandler(NSString* method, id args, FlutterResult methodResult) {
// UIImage::getFrame
if ([@"UIView::getFrame" isEqualToString:method]) {
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
CGRect rect = [target frame];
NSValue *dataValue = [NSValue value:&rect withObjCType:@encode(CGRect)];
methodResult(dataValue);
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::getHidden" isEqualToString:method]) {
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
methodResult(@(target.isHidden));
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::rotate" isEqualToString:method]) {
NSNumber* angle = (NSNumber*) args[@"angle"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
target.transform = CGAffineTransformMakeRotation([angle doubleValue] / 180.0 * M_PI);
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::create" isEqualToString:method]) {
UIView* result = [[UIView alloc] init];
methodResult(result);
} else if ([@"UIView::setHidden" isEqualToString:method]) {
NSNumber* hidden = (NSNumber*) args[@"hidden"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
target.hidden = [hidden boolValue];
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::setAnchorPoint" isEqualToString:method]) {
NSNumber* anchorU = (NSNumber*) args[@"anchorU"];
NSNumber* anchorV = (NSNumber*) args[@"anchorV"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
target.layer.anchorPoint = CGPointMake([anchorU doubleValue], [anchorV doubleValue]);
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::scaleWithDuration" isEqualToString:method]) {
NSNumber* duration = (NSNumber*) args[@"duration"];
NSNumber* fromValue = (NSNumber*) args[@"fromValue"];
NSNumber* toValue = (NSNumber*) args[@"toValue"];
NSNumber* repeatCount = (NSNumber*) args[@"repeatCount"];
NSNumber* repeatMode = (NSNumber*) args[@"repeatMode"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = fromValue;
animation.toValue = toValue;
animation.duration = [duration doubleValue];
animation.autoreverses = [repeatMode intValue] == 0 ? NO : YES;
animation.repeatCount = [repeatCount intValue] == 0 ? MAXFLOAT : [repeatCount intValue];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[target.layer addAnimation:animation forKey:@"zoom"];
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::translateWithDuration" isEqualToString:method]) {
NSNumber* duration = (NSNumber*) args[@"duration"];
NSNumber* toX = (NSNumber*) args[@"toX"];
NSNumber* toY = (NSNumber*) args[@"toY"];
NSNumber* repeatCount = (NSNumber*) args[@"repeatCount"];
NSNumber* repeatMode = (NSNumber*) args[@"repeatMode"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake([toX floatValue], [toY floatValue])];
animation.duration = [duration doubleValue];
animation.autoreverses = [repeatMode intValue] == 0 ? NO : YES;
animation.repeatCount = [repeatCount intValue] == 0 ? MAXFLOAT : [repeatCount intValue];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[target.layer addAnimation:animation forKey:@"position"];
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::alphaWithDuration" isEqualToString:method]) {
NSNumber* duration = (NSNumber*) args[@"duration"];
NSNumber* fromValue = (NSNumber*) args[@"fromValue"];
NSNumber* toValue = (NSNumber*) args[@"toValue"];
NSNumber* repeatCount = (NSNumber*) args[@"repeatCount"];
NSNumber* repeatMode = (NSNumber*) args[@"repeatMode"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = fromValue;
animation.toValue = toValue;
animation.duration = [duration doubleValue];
animation.autoreverses = [repeatMode intValue] == 0 ? NO : YES;
animation.repeatCount = [repeatCount intValue] == 0 ? MAXFLOAT : [repeatCount intValue];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[target.layer addAnimation:animation forKey:@"opacity"];
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::rotateWithDuration" isEqualToString:method]) {
NSNumber* duration = (NSNumber*) args[@"duration"];
NSNumber* fromValue = (NSNumber*) args[@"fromValue"];
NSNumber* toValue = (NSNumber*) args[@"toValue"];
NSNumber* repeatCount = (NSNumber*) args[@"repeatCount"];
NSNumber* repeatMode = (NSNumber*) args[@"repeatMode"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue = fromValue;
animation.toValue = toValue;
animation.duration = [duration doubleValue];
animation.autoreverses = [repeatMode intValue] == 0 ? NO : YES;
animation.repeatCount = [repeatCount intValue] == 0 ? MAXFLOAT : [repeatCount intValue];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[target.layer addAnimation:animation forKey:@"rotation"];
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else if ([@"UIView::groupWithDuration" isEqualToString:method]) {
NSNumber* duration = (NSNumber*) args[@"duration"];
NSArray<NSNumber*>* fromValue = (NSArray<NSNumber*>*) args[@"fromValue"];
NSArray<NSNumber*>* toValue = (NSArray<NSNumber*>*) args[@"toValue"];
NSArray<NSString*>* keyPath = (NSArray<NSString*>*) args[@"keyPath"];
NSNumber* repeatCount = (NSNumber*) args[@"repeatCount"];
NSNumber* repeatMode = (NSNumber*) args[@"repeatMode"];
UIView *target = (UIView *) args[@"__this__"];
if (target != nil && (NSNull*) target != [NSNull null]) {
NSMutableArray<CAAnimation*>* animations = [NSMutableArray arrayWithCapacity:[fromValue count]];
for (NSUInteger i = 0; i < animations.count; i++) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath[i]];
animation.fromValue = fromValue[i];
animation.toValue = toValue[i];
[animations addObject:animation];
}
CAAnimationGroup *group = [CAAnimationGroup animation];
group.duration = [duration doubleValue];
group.autoreverses = [repeatMode intValue] == 0 ? NO : YES;
group.repeatCount = [repeatCount intValue] == 0 ? MAXFLOAT : [repeatCount intValue];
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
[group setAnimations:animations];
[target.layer addAnimation:group forKey:@"group"];
methodResult(@"success");
} else {
methodResult([FlutterError errorWithCode:@"目标对象为nul"
message:@"目标对象为nul"
details:@"目标对象为nul"]);
}
} else {
methodResult(FlutterMethodNotImplemented);
}
}

View File

@ -0,0 +1,29 @@
//
// UIViewFactory.h
// foundation_fluttify
//
// Created by Yohom Bao on 2020/4/17.
//
#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIViewFactory : NSObject <FlutterPlatformViewFactory>
- (instancetype)initWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar;
@property(nonatomic) NSObject<FlutterPluginRegistrar>* registrar;
@end
@interface UIViewPlatformView : NSObject <FlutterPlatformView>
- (instancetype)initWithViewId:(int64_t)viewId frame:(CGRect)frame registrar:(NSObject <FlutterPluginRegistrar> *)registrar;
@property(nonatomic) NSObject<FlutterPluginRegistrar>* registrar;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,60 @@
//
// UIViewFactory.m
// foundation_fluttify
//
// Created by Yohom Bao on 2020/4/17.
//
#import "UIViewFactory.h"
#import "FoundationFluttifyPlugin.h"
// Dart
extern NSMutableDictionary<NSString *, NSObject *> *HEAP;
@implementation UIViewFactory {
}
- (instancetype)initWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_registrar = registrar;
}
return self;
}
- (NSObject <FlutterPlatformView> *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args {
return [[UIViewPlatformView alloc] initWithViewId:viewId frame: frame registrar:_registrar];
}
@end
@implementation UIViewPlatformView {
int64_t _viewId;
CGRect _frame;
UIView* _view;
}
- (instancetype)initWithViewId:(int64_t)viewId frame:(CGRect)frame registrar:(NSObject <FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_viewId = viewId;
_registrar = registrar;
_frame = frame;
}
return self;
}
- (UIView *)view {
if (_view == nil) {
_view = [[UIView alloc] initWithFrame:_frame];
}
// magic numberid
HEAP[[NSString stringWithFormat:@"%@", @(2147483647 - _viewId)]] = _view;
HEAP[[NSString stringWithFormat:@"%@:%@", @"UIView", @(_view.hash)]] = _view;
return _view;
}
@end