从iOS到Flutter开发的转变过程

初识

第一次接触Flutter是在2019年底。
Flutter发布时间不长, 当时没有深入的接触,尝试着装了开发环境,诸如遇到了很多问题Java安装、AndroidStudio安装、FlutterSDK下载、被墙等。
看着文档查着资料一步步的去解决,所幸最后安装成功了,运行了Deom,因为当时在做其他项目没有做更深入的接触。
随后,因手中的项目已经上线有了空余时间,加上公司要开发新项目并鼓励使用Flutter来做,便开始了Flutter的研究及开发。
由于之前搭建过环境的机器已更换,所以又重新搭建了Flutter环境在新的Mac上,也借此机会重新熟悉了一次环境搭建过程并做了文字记录,便于日后查找并发布到了平台上。
欢迎交流,记录见:Mac安装Flutter开发环境
Flutter因其多平台的统一性使得公司及个人开发者而言有明显的经济性效益提升。

语言转换感言

因为之前一直在做iOS开发,项目大多用Objective-C少量涉及Swift,而Flutter是Google基于Dart语言开发的,Dart语言相较于Objective-C差别还是很大的,都说Objective-C是计算机语言中一个另类,其实也不为过。

学习资料推荐

Flutter实战》电子书
Flutter中国开源项目

编辑器选择

iOS:Xcode(也只能用Xcode,是一款很优秀的编辑器)
Flutter:VSCode、Android Studio等,经过这一段时间的使用个人认为在Mac上使用VSCode更好一些,页面过度平滑,使用时卡顿很少而且各种配置功能很多,文件创建等相对便捷。

语言规则的对比

属性声明

Objective-C:

@property(nonatomic, assign) NSUInteger saveLimit;
@property(nonatomic, weak) id<DRLLogDelegate> delegate;

Dart:

  int connectTimeout = 10000;
  Map headers = {};

方法声明

Objective-C:

- (void)addLog:(nonnull NSString *)content;

Dart:

processObtainRequest({NetworkRequest request}) {}

对象创建

Objective-C:

DRLLogMessage *message = [DRLLogMessage new];

Dart:

  Dio dio = Dio();

方法回调

Objective-C:

/// 接收回调
[commodityPuchaseGoodsRequest startWithSuccess:^(DNResponse *response) {

    } failure:^(NSError *error) {
        
    }];

/// 发起回调
- (void)startWithSuccess:(DNRequestSuccessBlock)success failure:(DNRequestFailureBlock)failure {
    __weak typeof(self) weakSelf = self;
    DNResponse * response = [DNResponse new];
    NSError *parseError = [NSError new];
    if(success) {
        success(response);
        
    }
    if (failure) {
        failure(parseError);
        
    }
}

Dart:

/// 接收回调
MineInformationUpdateGenderRequest(gender: age).start((response) {

    }, (errorResponse) {

    });

/// 发起回调
post(String urlPath, {Map<String, dynamic> parameter, Map<String, String> header, ResponceSuccess successBlock, ResponceError failureBlock, NetworkContentType contentType = NetworkContentType.applicationJson}) async {
    Response response;
    Map lastMap = parameter;
    try {
        response = await _dio.post(urlPath, data: lastMap);

      if (successBlock != null) {
        successBlock(response);

      }

    } on DioError catch (error) {
      Response errorRespones;
      if (failureBlock != null) {
        failureBlock(errorRespones);
      }
    }
  }

工程建立

iOS:
Xcode创建

Flutter:
终端、Android Studio VScode等

设计模式的选择

iOS 一些小型项目通常采用MVC结构 中大型项目会采用MVVM等结构
Flutter因底层结构生命周期和内存管理机制会在设计模式上与iOS所使用的有些不同。
代理模式
iOS

///Log.h
@protocol LogDelegate <NSObject>

@optional
- (void)newLogMessage:(DRLLogMessage *)logMessage;

@end

@interface Log : NSObject

@property(nonatomic, weak) id<LogDelegate> delegate;

+ (instancetype)sharedLog;

@end

///Log.m
@implementation DRLLog
- (void)addLogWithType:(DRLLogType)type title:(nullable NSString *)title desc:(nullable NSString *)desc  {
      if ([weakSelf.delegate respondsToSelector:@selector(newLogMessage:)]) {
          [weakSelf.delegate newLogMessage:message];
       }
}
@end

///delegate.m
@interface DRLLogBrowseViewController ()<LogDelegate>
@property(nonatomic, strong) Log *logManager;
@end

@implementation DRLLogBrowseViewController
- (void)createContent {
    self.logManager = [DRLLog sharedLog];
    self.logManager.delegate = self;
}

- (void)newLogMessage:(DRLLogMessage *)logMessage {
//Do
}

@end

Flutter 要使用到 mixin 的超类


mixin NetworkInterceptorsDelegate {
  void onRequestDone(RequestOptions options, RequestInterceptorHandler handler);
  void onResponseDone(Response response, ResponseInterceptorHandler handler);
  void onErrorDone(DioError err, ErrorInterceptorHandler handler);
}

class NetworkLog with NetworkInterceptorsDelegate {
 void onRequestDone(RequestOptions options, RequestInterceptorHandler handler) {
//Do
 }
}

class NetworkInterceptors  {
  NetworkInterceptorsDelegate delegate;

  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    // TODO: implement onRequest
    super.onRequest(options, handler);

    if (delegate != null) {
      delegate.onRequestDone(options, handler);
    }
  }
}

代码管理

iOS Flutter基本一致 Git SVN都适用;

第三方框架、插件的使用和选择

Flutter因其高度的开源性非常收到开发者们的青睐,有很多优秀的开源项目开源框架在Github中,且开发势头有暴增的趋势,
Flutter开发常用第三方库分享

UI搭建的转变

Flutter有着高度封装的UI模块,很多样式都可以找到现成的官方或第三方已搭建好的样式,
列表加载优化

生命周期

iOS生命周期

AppDelegate

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions {
    return YES;
}
//在App启动时调用表示应用加载进程已经开始,常用来处理应用状态的存储和恢复。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}
// 表示App将从未运行状态进入运行状态,用于对App的初始化操作。
- (void)applicationDidBecomeActive:(UIApplication *)application{}
// 当应用即将进入前台运行时调用。
- (void)applicationWillResignActive:(UIApplication *)application{}
// 当应用开始在后台运行的时候调用。
- (void)applicationDidEnterBackground:(UIApplication *)application{}
// 当程序从后台将要重新回到前台(但是还没变成Active状态)时候调用。
- (void)applicationWillEnterForeground:(UIApplication *)application{}
// 已经从后台进入前台
- (void)applicationDidBecomeActive:(UIApplication *)application{}
// 当前应用即将被终止,在终止前调用的函数。通常是用来保存数据和一些退出前的清理工作。如果应用当前处在suspended,此方法不会被调用。 该方法最长运行时限为5秒,过期应用即被kill掉并且移除内存。
- (void)applicationWillTerminate:(UIApplication *)application{}

控制器(ViewController)

// 1.init初始化
- (instancetype)init{
    if (self = [super init]) {
    }
    return self;
}
// 2.Nib加载成功 当时xib加载时
- (void)awakeFromNib{
    [super awakeFromNib];
}
// 3.加载view。
- (void)loadView{
    [super loadView];
}
// 4.载入完成,可以进行自定义数据以及动态创建其他控件
- (void)viewDidLoad {
    [super viewDidLoad];
}
// 5.视图将出现在屏幕之前
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
}
// 6.将要对子视图进行调整
- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
}
// 7.对子视图进行调整完毕
- (void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];
}
// 8.视图已在屏幕上渲染完成
- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
}
// 9.视图将被从屏幕上移除
- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
}
// 10.视图已经被从屏幕上移除
- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
}
// 11.视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放
- (void)dealloc{
}
// 12.内存警告
- (void)didReceiveMemoryWarning{
    [super didReceiveMemoryWarning];
}

视图(View)

// 1.当视图添加子视图时调用
- (void)didAddSubview:(UIView *)subview{
    [super didAddSubview:subview];
}
// 2.当子视图从本视图移除时调用
- (void)willRemoveSubview:(UIView *)subview{
    [super willRemoveSubview:subview];
}
// 3.当视图即将加入父视图时 / 当视图即将从父视图移除时调用
- (void)willMoveToSuperview:(nullable UIView *)newSuperview{
    [super willMoveToSuperview:newSuperview];
}
// 4.当视图加入父视图时 / 当视图从父视图移除时调用
- (void)didMoveToSuperview{
    [super didMoveToSuperview];
}
// 5.当视图即将加入window视图时 / 当视图即将从window视图移除时调用
- (void)willMoveToWindow:(nullable UIWindow *)newWindow{
    [super willMoveToWindow:newWindow];
}
// 6.当视图加入window视图时 / 当视图从window视图移除时调用
- (void)didMoveToWindow{
    [super didMoveToWindow];
}

Flutter Widget 生命周期

内存管理机制

iOS:采用引用计数器对内存进行管理;分为手动引用计数(MRC)和自动引用计数(ARC),OC的内存机制可以简单概括为:谁持有(retain)谁释放(release)。retain引用计数+1,release反之。

Flutter:而在Flutter中与之对应的是另外一套内存管理机制,垃圾收集器;与Java有一些相似的地方
也整理了一部分关于这方面的资料: Flutter:内存管理机制(内存释放、垃圾回收机制)

网络

iOS

AFNetworking,作为一个成熟的第三方方案被运用到绝大多数iOS项目中,在实际开发中我们一般会对AFNetworking进行业务层的二次封装,以便我们拓展出符合业务场景的功能。

Flutter

dio
针对dio我做了一些二次封装:Flutter 网络层封装(dio封装)
这层封装更多的是偏向于实际中的项目开发,更适用于一些中大型项目;

图片加载

iOS

SDWebImage,成熟的第三方网络图片加载方案,有针对图片加载的多极缓存优化,列表图片加载的优化,图片缓存管理等,功能丰富实用简单;

Flutter

cached_network_image,

Flutter开发中遇到的问题

在实际开发中遇到的问题做了整理归纳:Flutter开发相关问题汇总

未完待续

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容