1
This commit is contained in:
12
ios/Classes/CGPointHandler.h
Normal file
12
ios/Classes/CGPointHandler.h
Normal 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
|
98
ios/Classes/CGPointHandler.m
Normal file
98
ios/Classes/CGPointHandler.m
Normal 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);
|
||||
}
|
||||
}
|
15
ios/Classes/CGRectHandler.h
Normal file
15
ios/Classes/CGRectHandler.h
Normal 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
|
78
ios/Classes/CGRectHandler.m
Normal file
78
ios/Classes/CGRectHandler.m
Normal 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);
|
||||
}
|
||||
}
|
||||
|
15
ios/Classes/CGSizeHandler.h
Normal file
15
ios/Classes/CGSizeHandler.h
Normal 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
|
52
ios/Classes/CGSizeHandler.m
Normal file
52
ios/Classes/CGSizeHandler.m
Normal 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);
|
||||
}
|
||||
}
|
||||
|
24
ios/Classes/FluttifyMessageCodec.h
Normal file
24
ios/Classes/FluttifyMessageCodec.h
Normal 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
|
230
ios/Classes/FluttifyMessageCodec.m
Normal file
230
ios/Classes/FluttifyMessageCodec.m
Normal 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也自动转换了, 但是fluttify需要的是NSData对象, 所以这里去掉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
|
9
ios/Classes/FoundationFluttifyPlugin.h
Normal file
9
ios/Classes/FoundationFluttifyPlugin.h
Normal 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
|
410
ios/Classes/FoundationFluttifyPlugin.m
Normal file
410
ios/Classes/FoundationFluttifyPlugin.m
Normal 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
|
12
ios/Classes/NSDataHandler.h
Normal file
12
ios/Classes/NSDataHandler.h
Normal 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
|
36
ios/Classes/NSDataHandler.m
Normal file
36
ios/Classes/NSDataHandler.m
Normal 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);
|
||||
}
|
||||
}
|
15
ios/Classes/NSDateHandler.h
Normal file
15
ios/Classes/NSDateHandler.h
Normal 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
|
27
ios/Classes/NSDateHandler.m
Normal file
27
ios/Classes/NSDateHandler.m
Normal 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);
|
||||
}
|
||||
}
|
15
ios/Classes/NSErrorHandler.h
Normal file
15
ios/Classes/NSErrorHandler.h
Normal 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
|
39
ios/Classes/NSErrorHandler.m
Normal file
39
ios/Classes/NSErrorHandler.m
Normal 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);
|
||||
}
|
||||
}
|
||||
|
15
ios/Classes/NSObjectHandler.h
Normal file
15
ios/Classes/NSObjectHandler.h
Normal 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
|
32
ios/Classes/NSObjectHandler.m
Normal file
32
ios/Classes/NSObjectHandler.m
Normal 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);
|
||||
}
|
||||
}
|
15
ios/Classes/PlatformService.h
Normal file
15
ios/Classes/PlatformService.h
Normal 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
|
352
ios/Classes/PlatformService.m
Normal file
352
ios/Classes/PlatformService.m
Normal 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);
|
||||
}
|
||||
// viewId转refId
|
||||
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);
|
||||
}
|
||||
}
|
15
ios/Classes/UIColorHandler.h
Normal file
15
ios/Classes/UIColorHandler.h
Normal 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
|
29
ios/Classes/UIColorHandler.m
Normal file
29
ios/Classes/UIColorHandler.m
Normal 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);
|
||||
}
|
||||
}
|
||||
|
12
ios/Classes/UIEdgeInsetsHandler.h
Normal file
12
ios/Classes/UIEdgeInsetsHandler.h
Normal 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
|
74
ios/Classes/UIEdgeInsetsHandler.m
Normal file
74
ios/Classes/UIEdgeInsetsHandler.m
Normal 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);
|
||||
}
|
||||
}
|
13
ios/Classes/UIImageHandler.h
Normal file
13
ios/Classes/UIImageHandler.h
Normal 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
|
69
ios/Classes/UIImageHandler.m
Normal file
69
ios/Classes/UIImageHandler.m
Normal 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);
|
||||
}
|
||||
}
|
15
ios/Classes/UIImageViewHandler.h
Normal file
15
ios/Classes/UIImageViewHandler.h
Normal 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
|
24
ios/Classes/UIImageViewHandler.m
Normal file
24
ios/Classes/UIImageViewHandler.m
Normal 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);
|
||||
}
|
||||
}
|
15
ios/Classes/UIViewControllerHandler.h
Normal file
15
ios/Classes/UIViewControllerHandler.h
Normal 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
|
21
ios/Classes/UIViewControllerHandler.m
Normal file
21
ios/Classes/UIViewControllerHandler.m
Normal 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);
|
||||
}
|
||||
}
|
12
ios/Classes/UIViewHandler.h
Normal file
12
ios/Classes/UIViewHandler.h
Normal 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
210
ios/Classes/UIViewHandler.m
Normal 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);
|
||||
}
|
||||
}
|
29
ios/Classes/platform_view/UIViewFactory.h
Normal file
29
ios/Classes/platform_view/UIViewFactory.h
Normal 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
|
60
ios/Classes/platform_view/UIViewFactory.m
Normal file
60
ios/Classes/platform_view/UIViewFactory.m
Normal 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 number调整一下id
|
||||
HEAP[[NSString stringWithFormat:@"%@", @(2147483647 - _viewId)]] = _view;
|
||||
HEAP[[NSString stringWithFormat:@"%@:%@", @"UIView", @(_view.hash)]] = _view;
|
||||
return _view;
|
||||
}
|
||||
|
||||
@end
|
||||
|
Reference in New Issue
Block a user