init project
This commit is contained in:
68
ios/Classes/Util/AMapConvertUtil.h
Normal file
68
ios/Classes/Util/AMapConvertUtil.h
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// AMapConvertUtil.h
|
||||
// amap_map
|
||||
//
|
||||
// Created by lly on 2020/10/30.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
#import <Flutter/Flutter.h>
|
||||
#import <MAMapKit/MAMapKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class MATouchPoi;
|
||||
|
||||
@interface AMapConvertUtil : NSObject
|
||||
|
||||
/// 经纬度坐标转字符串
|
||||
/// @param coordinate 经纬度坐标
|
||||
+ (NSString *)stringFromCoordinate:(CLLocationCoordinate2D)coordinate;
|
||||
|
||||
/// 颜色的色值解析(色值必须为json中的number类型)
|
||||
/// @param numberColor 色值
|
||||
+ (UIColor*)colorFromNumber:(NSNumber*)numberColor;
|
||||
|
||||
/// 将数组(内含数字)转换为point坐标,(默认数组第一个元素为x值,第二个为y值)
|
||||
/// @param data 数组
|
||||
+ (CGPoint)pointFromArray:(NSArray*)data;
|
||||
|
||||
/// 从数据中解析经纬度
|
||||
/// @param array 经纬度数组对(默认第一个当做维度,第二个当做经度)
|
||||
+ (CLLocationCoordinate2D)coordinateFromArray:(NSArray *)array;
|
||||
|
||||
/// 经纬度转json数组
|
||||
/// @param coord 经纬度
|
||||
+ (NSArray *)jsonFromCoordinate:(CLLocationCoordinate2D )coord;
|
||||
|
||||
/// 经纬度转json数组
|
||||
/// @param coordinate 经纬度
|
||||
+ (NSArray<NSNumber *> *)jsonArrayFromCoordinate:(CLLocationCoordinate2D)coordinate;
|
||||
|
||||
+ (UIImage*)imageFromRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar iconData:(NSArray*)iconData;
|
||||
|
||||
|
||||
/// 检测图标相关的描述,是否修改过
|
||||
/// @param previousIcon 之前的图标
|
||||
/// @param currentIcon 当前新的图标
|
||||
/// @return 修改了,则返回yes,否则返回NO
|
||||
+ (BOOL)checkIconDescriptionChangedFrom:(NSArray *)previousIcon to:(NSArray *)currentIcon;
|
||||
|
||||
|
||||
/// 经纬度坐标比较
|
||||
/// @param coord1 坐标1
|
||||
/// @param coord2 坐标2
|
||||
+ (BOOL)isEqualWith:(CLLocationCoordinate2D)coord1 to:(CLLocationCoordinate2D)coord2;
|
||||
|
||||
/// TouchPOI转字典
|
||||
/// @param poi 点击POI
|
||||
+ (NSDictionary *)dictFromTouchPOI:(MATouchPoi *)poi;
|
||||
|
||||
/// 解析得到mapRect结构
|
||||
/// @param array json数组[southwest,northeast],分别为西南、东北的坐标
|
||||
+ (MAMapRect)mapRectFromArray:(NSArray *)array;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
215
ios/Classes/Util/AMapConvertUtil.m
Normal file
215
ios/Classes/Util/AMapConvertUtil.m
Normal file
@ -0,0 +1,215 @@
|
||||
//
|
||||
// AMapConvertUtil.m
|
||||
// amap_map
|
||||
//
|
||||
// Created by lly on 2020/10/30.
|
||||
//
|
||||
|
||||
#import "AMapConvertUtil.h"
|
||||
|
||||
@implementation AMapConvertUtil
|
||||
|
||||
|
||||
/// 经纬度坐标转字符串
|
||||
/// @param coordinate 经纬度坐标
|
||||
+ (NSString *)stringFromCoordinate:(CLLocationCoordinate2D)coordinate {
|
||||
return [NSString stringWithFormat:@"{%.6f,%.6f}", coordinate.longitude, coordinate.latitude];
|
||||
}
|
||||
|
||||
+ (UIColor*)colorFromNumber:(NSNumber*)numberColor {
|
||||
if (numberColor == nil || [numberColor isKindOfClass:[NSNumber class]] == NO) {
|
||||
return nil;
|
||||
}
|
||||
unsigned long value = [numberColor unsignedLongValue];
|
||||
return [UIColor colorWithRed:((float)((value & 0xFF0000) >> 16)) / 255.0
|
||||
green:((float)((value & 0xFF00) >> 8)) / 255.0
|
||||
blue:((float)(value & 0xFF)) / 255.0
|
||||
alpha:((float)((value & 0xFF000000) >> 24)) / 255.0];
|
||||
}
|
||||
|
||||
+ (CGPoint)pointFromArray:(NSArray*)data {
|
||||
NSAssert((data != nil && [data isKindOfClass:[NSArray class]] && data.count == 2), @"数组类型转point格式错误");
|
||||
return CGPointMake([data[0] doubleValue],
|
||||
[data[1] doubleValue]);
|
||||
}
|
||||
|
||||
/// 从数据中解析经纬度
|
||||
/// @param array 经纬度数组对(默认第一个当做维度,第二个当做经度)
|
||||
+ (CLLocationCoordinate2D)coordinateFromArray:(NSArray *)array {
|
||||
CLLocationCoordinate2D location = kCLLocationCoordinate2DInvalid;
|
||||
if (array.count == 2) {
|
||||
double latitude = [array[0] doubleValue];
|
||||
double longitude = [array[1] doubleValue];
|
||||
if ([self checkValidLatitude:latitude longitude:longitude]) {
|
||||
location = CLLocationCoordinate2DMake(latitude, longitude);
|
||||
} else if ([self checkValidLatitude:longitude longitude:latitude]) {//交换二者
|
||||
location = CLLocationCoordinate2DMake(longitude, latitude);
|
||||
} else {
|
||||
NSLog(@"经纬度参数异常,解析为无效经纬度");
|
||||
}
|
||||
} else {
|
||||
NSLog(@"经纬度参数异常,解析为无效经纬度");
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
+ (NSArray *)jsonFromCoordinate:(CLLocationCoordinate2D )coord {
|
||||
if (CLLocationCoordinate2DIsValid(coord)) {
|
||||
return @[@(coord.latitude),@(coord.longitude)];
|
||||
} else {
|
||||
NSLog(@"经纬度无效,返回为空");
|
||||
return @[];
|
||||
}
|
||||
}
|
||||
|
||||
/// 检测经纬度是否有效
|
||||
/// @param latitude 维度
|
||||
/// @param longitude 经度
|
||||
+ (BOOL)checkValidLatitude:(double)latitude longitude:(double)longitude {
|
||||
if (latitude > 90 || latitude < -90) {
|
||||
return false;
|
||||
}
|
||||
if (longitude > 180 || longitude < -180) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+ (NSArray<NSNumber *> *)jsonArrayFromCoordinate:(CLLocationCoordinate2D)coordinate {
|
||||
if (CLLocationCoordinate2DIsValid(coordinate)) {
|
||||
return @[ @(coordinate.latitude), @(coordinate.longitude) ];
|
||||
} else {
|
||||
return @[];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (UIImage*)scaleImage:(UIImage*)image param:(NSNumber*)scaleParam {
|
||||
double scale = 1.0;
|
||||
if ([scaleParam isKindOfClass:[NSNumber class]]) {
|
||||
scale = scaleParam.doubleValue;
|
||||
}
|
||||
if (fabs(scale - 1) > 1e-3) {
|
||||
return [UIImage imageWithCGImage:[image CGImage]
|
||||
scale:(image.scale * scale)
|
||||
orientation:(image.imageOrientation)];
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
+ (UIImage*)imageFromRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar iconData:(NSArray*)iconData {
|
||||
UIImage* image;
|
||||
if ([iconData.firstObject isEqualToString:@"defaultMarker"]) {
|
||||
image = [UIImage imageNamed:[registrar lookupKeyForAsset:@"packages/amap_map/res/marker_default.png"]];//默认的图片资源
|
||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
||||
image = [self scaleImage:image param:[NSNumber numberWithFloat:screenScale]];
|
||||
//添加默认图片
|
||||
} else if ([iconData.firstObject isEqualToString:@"fromAsset"]) {
|
||||
if (iconData.count == 2) {
|
||||
image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1]]];
|
||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
||||
image = [self scaleImage:image param:[NSNumber numberWithFloat:screenScale]];
|
||||
}
|
||||
} else if ([iconData.firstObject isEqualToString:@"fromAssetImage"]) {
|
||||
if (iconData.count == 3) {
|
||||
image = [UIImage imageNamed:[registrar lookupKeyForAsset:iconData[1]]];
|
||||
NSNumber* scaleParam = iconData[2];
|
||||
image = [self scaleImage:image param:scaleParam];
|
||||
} else {
|
||||
NSString* error =
|
||||
[NSString stringWithFormat:@"'fromAssetImage' should have exactly 3 arguments. Got: %lu",
|
||||
(unsigned long)iconData.count];
|
||||
NSException* exception = [NSException exceptionWithName:@"InvalidBitmapDescriptor"
|
||||
reason:error
|
||||
userInfo:nil];
|
||||
@throw exception;
|
||||
}
|
||||
} else if ([iconData[0] isEqualToString:@"fromBytes"]) {
|
||||
if (iconData.count == 2) {
|
||||
@try {
|
||||
FlutterStandardTypedData* byteData = iconData[1];
|
||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
||||
image = [UIImage imageWithData:[byteData data] scale:screenScale];
|
||||
} @catch (NSException* exception) {
|
||||
@throw [NSException exceptionWithName:@"InvalidByteDescriptor"
|
||||
reason:@"Unable to interpret bytes as a valid image."
|
||||
userInfo:nil];
|
||||
}
|
||||
} else {
|
||||
NSString* error = [NSString
|
||||
stringWithFormat:@"fromBytes should have exactly one argument, the bytes. Got: %lu",
|
||||
(unsigned long)iconData.count];
|
||||
NSException* exception = [NSException exceptionWithName:@"InvalidByteDescriptor"
|
||||
reason:error
|
||||
userInfo:nil];
|
||||
@throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/// 检测图标相关的描述,是否修改过
|
||||
/// @param previousIcon 之前的图标
|
||||
/// @param currentIcon 当前新的图标
|
||||
/// @return 修改了,则返回yes,否则返回NO
|
||||
+ (BOOL)checkIconDescriptionChangedFrom:(NSArray *)previousIcon to:(NSArray *)currentIcon {
|
||||
if (previousIcon.count != currentIcon.count) {
|
||||
return YES;
|
||||
}
|
||||
//两个数组的数量一样
|
||||
for (NSUInteger index = 0; index < previousIcon.count; index ++) {
|
||||
if ([previousIcon[index] isKindOfClass:[NSString class]]) {
|
||||
if ([previousIcon[index] isEqualToString:currentIcon[index]] == NO) {
|
||||
return YES;
|
||||
}
|
||||
} else if ([previousIcon[index] isKindOfClass:[NSNumber class]]) {
|
||||
if (fabs([previousIcon[index] doubleValue] - [currentIcon[index] doubleValue]) > 0.000001) {
|
||||
return YES;
|
||||
}
|
||||
} else {//其它数据无法比较,直接默认强制更新
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)isEqualWith:(CLLocationCoordinate2D)coord1 to:(CLLocationCoordinate2D)coord2 {
|
||||
if (fabs(coord1.latitude - coord2.latitude) > 0.000001 || fabs(coord1.longitude - coord2.longitude) > 0.000001) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)dictFromTouchPOI:(MATouchPoi *)poi {
|
||||
if (poi == nil) {
|
||||
return nil;
|
||||
}
|
||||
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
if (poi.name) {
|
||||
[dict setObject:poi.name forKey:@"name"];
|
||||
}
|
||||
if (CLLocationCoordinate2DIsValid(poi.coordinate)) {
|
||||
[dict setObject:[AMapConvertUtil jsonArrayFromCoordinate:poi.coordinate] forKey:@"latLng"];
|
||||
}
|
||||
if (poi.uid) {
|
||||
[dict setObject:poi.uid forKey:@"id"];
|
||||
}
|
||||
return [dict copy];
|
||||
}
|
||||
|
||||
+ (MAMapRect)mapRectFromArray:(NSArray *)array {
|
||||
NSAssert((array && [array isKindOfClass:[NSArray class]] && array.count == 2), @"解析mapRect的参数有误");
|
||||
CLLocationCoordinate2D southwest = [AMapConvertUtil coordinateFromArray:array[0]];
|
||||
CLLocationCoordinate2D northeast = [AMapConvertUtil coordinateFromArray:array[1]];
|
||||
MAMapPoint mapNorthEastPoint = MAMapPointForCoordinate(northeast);
|
||||
MAMapPoint mapSouthWestPoint = MAMapPointForCoordinate(southwest);
|
||||
double width = fabs(mapNorthEastPoint.x - mapSouthWestPoint.x);
|
||||
double height = fabs(mapNorthEastPoint.y - mapSouthWestPoint.y);
|
||||
MAMapRect limitRect = MAMapRectMake(mapSouthWestPoint.x, mapNorthEastPoint.y, width, height);
|
||||
return limitRect;
|
||||
}
|
||||
|
||||
|
||||
@end
|
35
ios/Classes/Util/AMapJsonUtils.h
Normal file
35
ios/Classes/Util/AMapJsonUtils.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// MAJsonUtils.h
|
||||
// amap_map
|
||||
//
|
||||
// Created by shaobin on 2019/2/13.
|
||||
// Copyright © 2019 Amap.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AMapJsonUtils : NSObject
|
||||
|
||||
/**
|
||||
model转为可序列化为json的对象。
|
||||
|
||||
@param model model对象:支持NSDictionary、NSArray、自定义类,且支持嵌套(Dict、Array内包含自定义类示例,或自定义类内包含Dict、Array) 注意如果自定义类或dict、array中包含非字符串、数字、布尔、null类型的属性,其行为是undefined的
|
||||
@return 返回NSArray或者NSDictionary对象,如果失败返回nil。
|
||||
*/
|
||||
+ (id)jsonObjectFromModel:(id)model;
|
||||
|
||||
/**
|
||||
dict转model
|
||||
|
||||
@param dict dict
|
||||
@param modelClass model对应的Class
|
||||
@return 返回modelClass实例
|
||||
*/
|
||||
+ (id)modelFromDict:(NSDictionary*)dict modelClass:(Class)modelClass;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
275
ios/Classes/Util/AMapJsonUtils.m
Normal file
275
ios/Classes/Util/AMapJsonUtils.m
Normal file
@ -0,0 +1,275 @@
|
||||
//
|
||||
// MAJsonUtils.m
|
||||
// amap_map
|
||||
//
|
||||
// Created by shaobin on 2019/2/13.
|
||||
// Copyright © 2019 Amap.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AMapJsonUtils.h"
|
||||
#import <objc/runtime.h>
|
||||
#import <objc/message.h>
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
#import "AMapConvertUtil.h"
|
||||
|
||||
@implementation AMapJsonUtils
|
||||
|
||||
+ (BOOL)isValidJsonValue:(id)value {
|
||||
if([value isKindOfClass:NSString.class] ||
|
||||
[value isKindOfClass:NSNumber.class] ||
|
||||
value == [NSNull null]) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (id)jsonValueFromObject:(id)obj {
|
||||
if([self isValidJsonValue:obj]) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if(!obj) {
|
||||
return [NSNull null];
|
||||
}
|
||||
|
||||
//常用基本类型判断,not exhausted
|
||||
if([obj isKindOfClass:NSDate.class] ||
|
||||
[obj isKindOfClass:NSData.class] ||
|
||||
[obj isKindOfClass:NSValue.class]) {
|
||||
NSString *retStr = [NSString stringWithFormat:@"%@", obj];
|
||||
return retStr;
|
||||
}
|
||||
|
||||
if([obj isKindOfClass:NSArray.class]) {
|
||||
NSArray *oldArray = (NSArray*)obj;
|
||||
NSMutableArray *retArray = [NSMutableArray arrayWithCapacity:[oldArray count]];
|
||||
for(id item in oldArray) {
|
||||
id jsonValue = [self jsonValueFromObject:item];
|
||||
[retArray addObject:jsonValue];
|
||||
}
|
||||
return retArray;
|
||||
}
|
||||
|
||||
if([obj isKindOfClass:NSDictionary.class]) {
|
||||
NSDictionary *oldDict = (NSDictionary *)obj;
|
||||
NSMutableDictionary *retDict = [NSMutableDictionary dictionaryWithCapacity:[oldDict count]];
|
||||
for(id key in [oldDict allKeys]) {
|
||||
id item = [oldDict objectForKey:key];
|
||||
id jsonValue = [self jsonValueFromObject:item];
|
||||
if(jsonValue) {
|
||||
[retDict setObject:jsonValue forKey:key];
|
||||
}
|
||||
}
|
||||
return retDict;
|
||||
}
|
||||
|
||||
NSArray *propertyArray = [self allPropertiesOfClass:[obj class]];
|
||||
NSMutableDictionary *returnDict = [NSMutableDictionary dictionaryWithCapacity:propertyArray.count];
|
||||
for(NSString *property in propertyArray) {
|
||||
id value = [obj valueForKey:property];
|
||||
if(value) {
|
||||
id jsonValue = [self jsonValueFromObject:value];
|
||||
NSString *mappedName = property;
|
||||
if(jsonValue) {
|
||||
[returnDict setObject:jsonValue forKey:mappedName];
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnDict;
|
||||
}
|
||||
|
||||
+ (id)jsonObjectFromModel:(id)model {
|
||||
id ret = [self jsonValueFromObject:model];
|
||||
if(![NSJSONSerialization isValidJSONObject:ret]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ (id)modelFromDict:(NSDictionary*)dict modelClass:(Class)modelClass {
|
||||
if(![dict isKindOfClass:[NSDictionary class]]) {
|
||||
NSLog(@"[AMap] the object must be of %@", [NSDictionary class]);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if([modelClass isSubclassOfClass:[NSDictionary class]]) {
|
||||
return [dict copy];
|
||||
}
|
||||
|
||||
//获取clazz属性列表
|
||||
NSArray *propertyArray = [self allPropertiesOfClass:modelClass];
|
||||
NSMutableArray* missedProperties = [NSMutableArray array];
|
||||
id ret = [[modelClass alloc] init];
|
||||
//枚举clazz中的每个属性,然后赋值
|
||||
for (NSString *propertyName in propertyArray) {
|
||||
NSString *keyName = propertyName;
|
||||
id value = [dict objectForKey:keyName];
|
||||
//'id'是关键字,服务端返回'id'字段属性名更改为'id_'
|
||||
if(!value && [propertyName isEqualToString:@"id_"]) {
|
||||
value = [dict objectForKey:@"id"];
|
||||
}
|
||||
if(!value) {
|
||||
[missedProperties addObject:propertyName];
|
||||
continue;
|
||||
}
|
||||
|
||||
if(value == [NSNull null]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class propertyClass = nil;
|
||||
objc_property_t property = class_getProperty(modelClass, [propertyName UTF8String]);
|
||||
NSString *propertyAttributes = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding];
|
||||
NSArray *splitPropertyAttributes = [propertyAttributes componentsSeparatedByString:@","];
|
||||
if(splitPropertyAttributes.count > 0) {
|
||||
NSString *encodeType = splitPropertyAttributes[0];
|
||||
if([encodeType hasPrefix:@"T@"]) {
|
||||
NSArray *splitEncodeType = [encodeType componentsSeparatedByString:@"\""];
|
||||
NSString *className = nil;
|
||||
if(splitEncodeType.count > 1) {
|
||||
className = splitEncodeType[1];
|
||||
}
|
||||
if(className) {
|
||||
propertyClass = NSClassFromString(className);
|
||||
}
|
||||
} else if ([encodeType isEqualToString:@"T{CLLocationCoordinate2D=dd}"]) {//经纬度
|
||||
//解析经纬度
|
||||
CLLocationCoordinate2D coordinate = [self coordinateFromModel:value];
|
||||
//使用msgSend直接设置经纬度的属性
|
||||
SEL sel = NSSelectorFromString([NSString stringWithFormat:@"set%@:",[propertyName capitalizedString]]);
|
||||
((void (*)(id,SEL,CLLocationCoordinate2D))objc_msgSend)(ret,sel,coordinate);
|
||||
continue;
|
||||
} else if ([encodeType isEqualToString:@"T{CGPoint=dd}"]) {//CGPoint点
|
||||
CGPoint point = [AMapConvertUtil pointFromArray:value];
|
||||
//使用msgSend直接设置经纬度的属性
|
||||
SEL sel = NSSelectorFromString([NSString stringWithFormat:@"set%@:",[propertyName capitalizedString]]);
|
||||
((void (*)(id,SEL,CGPoint))objc_msgSend)(ret,sel,point);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//获取property类型后,再处理
|
||||
if(propertyClass) {
|
||||
if([value isKindOfClass:propertyClass]) {
|
||||
//array 需要特殊处理
|
||||
if([propertyClass isSubclassOfClass:NSArray.class]) {
|
||||
NSString *elementClassSel = [NSString stringWithFormat:@"%@ElementClass", propertyName];
|
||||
SEL selector = NSSelectorFromString(elementClassSel);
|
||||
if([[ret class] respondsToSelector:selector]) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||
Class elementCls = [[ret class] performSelector:selector];
|
||||
#pragma clang diagnostic pop
|
||||
NSArray *arr = (NSArray *)value;
|
||||
NSMutableArray *mutArr = [NSMutableArray arrayWithCapacity:arr.count];
|
||||
for(id item in arr) {
|
||||
id newItem = [self modelFromDict:item modelClass:elementCls];
|
||||
if(newItem) {
|
||||
[mutArr addObject:newItem];
|
||||
} else {
|
||||
[mutArr addObject:item];
|
||||
}
|
||||
}
|
||||
[ret setValue:mutArr forKey:propertyName];
|
||||
} else {
|
||||
[ret setValue:value forKey:propertyName];
|
||||
}
|
||||
} else {
|
||||
[ret setValue:value forKey:propertyName];
|
||||
}
|
||||
} else if([value isKindOfClass:NSDictionary.class]){
|
||||
NSDictionary *tempDic = value;
|
||||
id model = [self modelFromDict:tempDic modelClass:propertyClass];
|
||||
[ret setValue:model forKey:propertyName];
|
||||
} else if ([value isKindOfClass:[NSNumber class]] && [NSStringFromClass(propertyClass) isEqualToString:@"UIColor"]) {
|
||||
UIColor *color = [AMapConvertUtil colorFromNumber:value];
|
||||
[ret setValue:color forKey:propertyName];
|
||||
} else {
|
||||
[ret setValue:value forKey:propertyName];
|
||||
#ifdef DEBUG
|
||||
Class valueClaz = [value class];
|
||||
NSLog(@"\U0001F913\U0001F913 Warning1: property '%@' of %@ is %@, %@ is received", propertyName, modelClass, propertyClass, valueClaz);
|
||||
#endif
|
||||
}
|
||||
} else { //end of if(propertyClaz) 如@"Ti" @"Tf"
|
||||
if([self isValidJsonValue:value]){
|
||||
[ret setValue:value forKey:propertyName];
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Class valueClaz = [value class];
|
||||
NSLog(@"\U0001F913\U0001F913 Warning1: property '%@' of %@ is %@, %@ is received", propertyName, modelClass, propertyClass, valueClaz);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if([missedProperties count] > 0) {
|
||||
NSLog(@"\U0001F913\U0001F913 Warning2: %@ value missed: %@", modelClass, missedProperties);
|
||||
}
|
||||
#endif
|
||||
|
||||
NSString *postHookSel = [NSString stringWithFormat:@"postHookWith:"];
|
||||
SEL sel = NSSelectorFromString(postHookSel);
|
||||
if([ret respondsToSelector:sel]) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||||
[ret performSelector:sel withObject:dict];
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//返回array of propertyNames
|
||||
+ (NSArray<NSString*> *)allPropertiesOfClass:(Class)cls {
|
||||
Class clazz = cls;
|
||||
|
||||
NSMutableArray *mutArr = [[NSMutableArray alloc] init];
|
||||
while(clazz != [NSObject class]) {
|
||||
unsigned int count = 0;
|
||||
objc_property_t* properties = class_copyPropertyList(clazz, &count);
|
||||
|
||||
for (int i = 0; i < count ; i++) {
|
||||
objc_property_t prop = properties[i];
|
||||
NSString *propertyName = [NSString stringWithCString:property_getName(prop) encoding:NSUTF8StringEncoding];
|
||||
[mutArr addObject:propertyName];
|
||||
}
|
||||
|
||||
if(properties) {
|
||||
free(properties);
|
||||
}
|
||||
|
||||
clazz = class_getSuperclass(clazz);
|
||||
}
|
||||
|
||||
return mutArr;
|
||||
}
|
||||
|
||||
|
||||
//从数据model中解析经纬度
|
||||
+ (CLLocationCoordinate2D)coordinateFromModel:(id)model {
|
||||
CLLocationCoordinate2D location = kCLLocationCoordinate2DInvalid;
|
||||
if ([model isKindOfClass:[NSArray class]]) {
|
||||
return [AMapConvertUtil coordinateFromArray:model];
|
||||
} else if ([model isKindOfClass:[NSString class]]) {//后台经纬度字符串习惯是(经度,维度)的格式
|
||||
NSString *coordStr = model;
|
||||
NSArray *array = [coordStr componentsSeparatedByString:@","];
|
||||
array = [[array reverseObjectEnumerator] allObjects];//这里需要逆置
|
||||
return [AMapConvertUtil coordinateFromArray:array];
|
||||
} else if ([model isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *dict = model;
|
||||
NSNumber *latitudeNum = [dict objectForKey:@"latitude"];
|
||||
NSNumber *longitudeNum = [dict objectForKey:@"longitude"];
|
||||
if (latitudeNum && longitudeNum) {
|
||||
location = CLLocationCoordinate2DMake([latitudeNum doubleValue], [longitudeNum doubleValue]);
|
||||
} else {
|
||||
NSLog(@"经纬度参数异常,解析为无效经纬度");
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
@end
|
27
ios/Classes/Util/AMapMethodCallDispatcher.h
Normal file
27
ios/Classes/Util/AMapMethodCallDispatcher.h
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// AMapMethodCallDispatcher.h
|
||||
// amap_map
|
||||
//
|
||||
// Created by lly on 2020/11/16.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Flutter/Flutter.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// methodCall的分发器,该对象以Category的形式设置给FlutterMethodChannel,作为FlutterMethodCallHandler,
|
||||
/// 再根据call.method来分发处理对应的处理block
|
||||
@interface AMapMethodCallDispatcher : NSObject
|
||||
|
||||
- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;
|
||||
|
||||
- (void)addMethodName:(NSString *)methodName withHandler:(FlutterMethodCallHandler)handler;
|
||||
|
||||
- (void)removeHandlerWithMethodName:(NSString *)methodName;
|
||||
|
||||
- (void)clearAllHandler;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
61
ios/Classes/Util/AMapMethodCallDispatcher.m
Normal file
61
ios/Classes/Util/AMapMethodCallDispatcher.m
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// AMapMethodCallDispatcher.m
|
||||
// amap_map
|
||||
//
|
||||
// Created by lly on 2020/11/16.
|
||||
//
|
||||
|
||||
#import "AMapMethodCallDispatcher.h"
|
||||
|
||||
@interface AMapMethodCallDispatcher ()
|
||||
|
||||
@property (nonatomic, strong) NSRecursiveLock *dictLock;
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary *callDict;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AMapMethodCallDispatcher
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.dictLock = [[NSRecursiveLock alloc] init];
|
||||
self.callDict = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
[self.dictLock lock];
|
||||
FlutterMethodCallHandler handle = [self.callDict objectForKey:call.method];
|
||||
[self.dictLock unlock];
|
||||
if (handle) {
|
||||
handle(call,result);
|
||||
} else {
|
||||
NSLog(@"call method:%@ handler is null",call.method);
|
||||
result(nil);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addMethodName:(NSString *)methodName withHandler:(FlutterMethodCallHandler)handler {
|
||||
NSAssert((methodName.length > 0 && handler != nil), @"添加methodCall回调处理参数异常");
|
||||
[self.dictLock lock];
|
||||
[self.callDict setObject:handler forKey:methodName];
|
||||
[self.dictLock unlock];
|
||||
}
|
||||
|
||||
- (void)removeHandlerWithMethodName:(NSString *)methodName {
|
||||
NSAssert(methodName.length > 0, @"移除methodCall时,参数异常");
|
||||
[self.dictLock lock];
|
||||
[self.callDict removeObjectForKey:methodName];
|
||||
[self.dictLock unlock];
|
||||
}
|
||||
|
||||
- (void)clearAllHandler {
|
||||
[self.dictLock lock];
|
||||
[self.callDict removeAllObjects];
|
||||
[self.dictLock unlock];
|
||||
}
|
||||
|
||||
@end
|
Reference in New Issue
Block a user