iOS开发进阶(一):走近iOS原生开发

news2024/9/25 17:19:08

文章目录

    • 一、前言
    • 二、知识储备
    • 三、 Object-C
    • 四、启动流程
    • 五、拓展阅读

一、前言

在应用 uni-app 进行跨平台APP开发过程中,发现并不支持视频播放小窗功能,且插件市场提供的插件用户体验不好,遂决定自行开发 uni-app 原生插件。

uni-app原生插件指的是将原生开发的功能按照规范封装成插件包,然后即可在 uni-app 前端项目中通过js调用开发的原生能力。

有关 iOS 原生开发环境搭建步骤,详参博文《跨平台应用开发进阶(二十七) iOS原生开发环境搭建步骤详解》。

二、知识储备

iOS目前流行两种开发语言:Objective-CSwiftObjective-C是一门面向对象的语言,并且是非常实用的语言。有C(C++)语言基础者上手会容易些;后者Swift是iOS/Mac未来开发的主要语言,无论从编程思想还是从api书写,都很不错。

  • 开发工具:Xcode

    Xcode 是iOS 开发必备工具, 运行于苹果公司的Mac操作系统下,是苹果公司向开发人员提供的集成开发环境,用于开发Mac OS X,iOS的应用程序。Xcode 具有统一的用户界面设计,编码、测试、调试都在一个简单的窗口内完成。当然你也可以使用APPcode

  • 类库管理工具:CocoaPods

    CocoaPods 应该是iOS最常用最有名的类库管理工具了,通过CocoaPods工具可以为项目添加被称为“Pods”的依赖库(这些类库必须是CocoaPods本身所支持的),并且可以轻松管理其版本。

三、 Object-C

鉴于 uni-app 原生插件使用 Object-C 实现。故后续开发语言以 Object-C 为主。

Objective-C,顾名思义,其扩展了标准的ANSI C语言,引入了 消息传递机制面向对象编程。(以下默认已具有C/C++语言基础)

语法概述:

  • 没有包名(命名空间)的概念:在Java中,为了防止两个类名相同的类冲突,可以将这2个类放在不同的包里面。OC中并没有”"的概念,也就是没有命名空间机制,取而代之的是开发人员给类名加上前缀,使用前缀可以有效的防止类名冲突。比如NSString(OC中的字符串类)、NSArray(OC的数组类),它们的前缀都是NS。

  • 关键字都以@开头:OC代码中是可以混入C语言、C++代码的,而C语言和C++作为一门编程语言,都有自己的关键字。为了防止跟C语言、C++关键字冲突,OC的关键字都以@开头。甚至字符串都是以@开头的,比如@“Hello"是OC中的字符串,而"Hello"则是C语言中的字符串。

语法要点:
在这里插入图片描述

  • Oc没有垃圾回收;

  • 源文件后缀为.m;入口程序同c,也是main();

  • 导包使用 #import 也不用使用条件编译加入头文件;#import会自动判断是否已经添加过该头文件。

  • .h文件:头文件,即类的声明文件,用于声明成员变量、方法。类的声明使用关键字@interface@end

    注意:.h中的方法只是做一个声明,并不对方法进行实现。也就是说,只是说明一下方法名、方法的返回值类型、方法接收的参数类型而已,并不会编写方法内部的代码。

  • .m文件:类的实现文件,可以包含Objective-CC 的代码,用于实现.h中声明的方法。类的实现使用关键字@implementation@end
    .mm文件:源代码文件,可以包含Objective-CC以及C++的代码。仅在需要使用C++特性时使用。

  • 头文件引用:除了可以使用#includeObjective-C 提供了更好的指令 #import确保相同的头文件仅会被包含一次(推荐使用这种方式)。

  • 消息传递Objective-C的面向对象语法源于Smalltalk消息传递风格。不同于c++等面向对象语言对象调用的说法,其采用对象之间消息传递的思想,天生具备动态绑定能力,允许传递未知的消息(编译器不报错),直到运行时才处理消息。反之,C++在编译期就会检查是否有对应的方法,若没有则报错。另外Objective-C也可以将消息发送给空对象,默认为不做任何事,不用担心程序崩溃,健壮性更强。

示例代码如下:

#import "TestModule.h"

@implementation TestModule

// 通过宏 UNI_EXPORT_METHOD 将异步方法暴露给 js 端
UNI_EXPORT_METHOD(@selector(testAsyncFunc:callback:))

/// 异步方法(注:异步方法会在主线程(UI线程)执行)
/// @param options js 端调用方法时传递的参数
/// @param callback 回调方法,回传参数给 js 端
- (void)testAsyncFunc:(NSDictionary *)options callback:(UniModuleKeepAliveCallback)callback {
    // options 为 js 端调用此方法时传递的参数
    NSLog(@"%@",options);
    
    // 可以在该方法中实现原生能力,然后通过 callback 回调到 js

    // 回调方法,传递参数给 js 端 注:只支持返回 String 或 NSDictionary (map) 类型
    if (callback) {
        // 第一个参数为回传给js端的数据,第二个参数为标识,表示该回调方法是否支持多次调用,如果原生端需要多次回调js端则第二个参数传 YES;
        callback(@"success",NO);
    }
}

// 通过宏 UNI_EXPORT_METHOD_SYNC 将同步方法暴露给 js 端
UNI_EXPORT_METHOD_SYNC(@selector(testSyncFunc:))

/// 同步方法(注:同步方法会在 js 线程执行)
/// @param options js 端调用方法时传递的参数
- (NSString *)testSyncFunc:(NSDictionary *)options {
    // options 为 js 端调用此方法时传递的参数
    NSLog(@"%@",options);

    /*
     可以在该方法中实现原生功能,然后直接通过 return 返回参数给 js
     */

    // 同步返回参数给 js 端 注:只支持返回 String 或 NSDictionary (map) 类型
    return @"success";
}

@end

四、启动流程

main函数如下:

//  程序启动时执 main函数,在main函数当中有以下操作.
#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
    //第三个参数:UIApplication类名或者子类的名称 nil == @"UIApplication" 
    //第四个参数:UIApplication的代理的代理名称
    //NSStringFromClass:把类名转化字符串
    //NSStringFromClass好处:1.有提示功能 2.避免输入错误
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

在这里插入图片描述

程序完整启动流程:

  1. 执行Main
  2. 执行UIApplicationMain函数。
  3. 创建UIApplication对象,并设置UIApplicationMain对象的代理。UIApplication的第三个参数就是UIApplication的名称,如果指定为nil,它会默认
    UIApplicationUIApplication的第四个参数为UIApplication的代理.。
  4. 开启一个主运行循环保证应用程序不退出。
  5. 加载 info.plist 配置文件。判断 info.plist 文件当中有没有Main storyboard file base name里面有没有指定storyboard文件,如果有就去加载 info.plist
    文件,如果没有,那么应用程序加载完毕。

五、拓展阅读

  • 《跨平台应用开发进阶(六) :uni-app实现原生插件集成》
  • 《跨平台应用开发进阶(五十九):uni-app实现视屏播放小窗功能》
  • 《跨平台应用开发进阶(二十七) iOS原生开发环境搭建步骤详解》
  • 《Learn iOS Programming》
  • 《 The Swift programming language Swift 4.2》
  • 《Learning iOS development on GitHub》
  • 《iOS Dev Weekly》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/709944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣 450. 删除二叉搜索树中的节点

题目来源&#xff1a;https://leetcode.cn/problems/delete-node-in-a-bst/description/ C题解1&#xff1a;迭代法。删除节点需要分情况讨论&#xff1a; 找不到节点&#xff0c;返回原根节点&#xff1b;删除节点无子节点&#xff0c;那么其父节点指向空就行&#xff08;注意…

Java前端编译与优化

一个编译器的前端把*.java文件转变成*.class文件的过程称为Java前端编译。像Javac这类前端编译器对代码的运行效率几乎没任何优化措施&#xff0c;但是其做了许多针对Java语言编码过程的优化措施来降低程序员的编码复杂度、提供编码效率。 1 Javac编译器 准备过程 初始化插入…

《PyTorch深度学习实践》第十讲 卷积神经网络(基础篇)

b站刘二大人《PyTorch深度学习实践》课程第十讲卷积神经网络&#xff08;基础篇&#xff09;笔记与代码&#xff1a;https://www.bilibili.com/video/BV1Y7411d7Ys?p10&vd_sourceb17f113d28933824d753a0915d5e3a90 上一讲中MNIST数据集的例子采用的是全连接神经网络&#…

自然语言处理从入门到应用——预训练模型总览:两大任务类型

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 从大量无标注数据中进行预训练使许多自然语言处理任务获得显著的性能提升。总的来看&#xff0c;预训练模型的优势包括&#xff1a; 在庞大的无标注数据上进行预训练可以获取更通用的语言表示&#xff0c;并有利于下游…

python语法(高阶)-多线程编程

""" 演示多线程编程的使用 """ import time import threadingdef sing(msg):while True:print(msg)time.sleep(1)return Nonedef dance(msg):while True:print(msg)time.sleep(1)return Noneif __name__ __main__:# 创建一个唱歌的线程&#xf…

后台管理系统的权限(vue如何实现后台管理系统的权限,react如何实现后台管理系统的权限)

一、权限的解释 一般来说&#xff0c;在后台管理系统里肯定会使用到权限&#xff0c;权限一般分为功能级权限和数据级权限 1、功能级权限 1&#xff09;、页面级权限&#xff08;菜单&#xff09;&#xff1a; 不同的用户&#xff08;角色&#xff09;登录到管理系统后&#…

mysql load data infile 报错 1290 处理方法

mysql load data infile 命令导入数据报错"16:06:13 load data infile “/var/lib/mysql/test/employee.csv” into table emp fields terminated by ‘,’ ignore 1 lines Error Code: 1290. The MySQL server is running with the --secure-file-priv option so it cann…

Linux应用层开发--多线程进程编程

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、linux开发的方向二、Linux环境特点介绍Linux环境基本构成 三、进程与线程1、进程的概念2、进程的状态3、线程的概念4、线…

leetcode 559. N 叉树的最大深度

2023.7.2 这道题还是使用层序遍历&#xff0c;在N叉树的层序遍历的基础上增加一个求深度的操作即可。下面上代码&#xff1a; class Solution { public:int maxDepth(Node* root) {int depth 0;queue<Node*> que;if(root nullptr) return 0;que.push(root);while(!que…

json 压缩算法详解

概要 无论使用何种编程语言&#xff0c;json格式的数据已被广泛应用&#xff0c;不论是数据的传输还是存储&#xff0c;在很多应用场景下&#xff0c;你可能想进一步地压缩JSON字符串的长度&#xff0c;以提升传输效率&#xff0c;如果你使用的是nosql数据库&#xff0c;你可能…

2012年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题——纯享题目版

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;考取过HCIE Cloud Computing、CCIE Security、CISP、RHCE、CCNP RS、PEST 3等证书。&#x1f433; &#x1f495;兴趣爱好&#xff1a;b站天天刷&…

记一次tomcat版本升级导致的现网问题

前言 最近公司项目做安全漏洞审查&#xff0c;把一批服务的fastjson,tomcat,log4j版本做升级&#xff0c;那天上线了50个服务&#xff0c;所有服务上线之后&#xff0c;现网有客服反馈录音笔下单异常。查询了现网日志&#xff0c;发现适配服务有异常信息&#xff0c;报错信息如…

闲人闲谈PS之四十二——顾问的“禁忌之地”—制造能力计划

惯例闲话&#xff1a;上个月有幸成为乐老师乐谈IT系列培训课程的讲师&#xff0c;分享主题是&#xff0c;PS在装备制造和工程行业的应用。虽然培训规模不是很大&#xff0c;但是闲人很有信心&#xff0c;至少在小范围之内&#xff0c;参与培训的听友人来说&#xff0c;PS一直以…

什么条件下会出现死锁,如何避免?

文章目录 一、什么是死锁二、产生死锁的原因&#xff1a;三、如何避免死锁&#xff1a; 一、什么是死锁 死锁&#xff0c;简单来说就是两个或者两个以上的线程在执行过程中&#xff0c;去争夺同一个共享资源导致相互等待的现象。如果没有外部干预&#xff0c;线程会一直处于阻塞…

图像的算术操作

1.图像的加法 用途&#xff1a;图像的合成 Rain图片View图片 合成代码&#xff1a; import numpy as np import cv2 as cv import matplotlib.pyplot as pltrain cv.imread(rain.png) plt.imshow(rain[:, :, ::-1]) plt.show()view cv.imread(view.png) plt.imshow(view…

773. 滑动谜题

链接&#xff1a;773. 滑动谜题 题解&#xff1a;https://blog.csdn.net/INGNIGHT/article/details/131350054 滑动拼图 II class Solution { public:int slidingPuzzle(vector<vector<int>>& board) {// 异常判断if (board.size() < 0 || board[0].size…

怎么管理好一个团队?

一个成功的企业需要一个高效、有能力、积极的团队来支持其业务运营。管理一个团队需要领导者具备一定的技能和知识&#xff0c;怎么管理好一个团队对于许多企业领导者而言也是一项不小的挑战。对此&#xff0c;我想首先推荐一本非常优秀的团队书籍——《经理人参阅&#xff1a;…

js vuejs dagre-d3绘制流程图实用指南 有向图可视化

写在前面 之前有小伙伴问我如何使用 D3 在前端绘制流程图,今天在这里给安排上,与大家分享。 明确一点,只要你的数据计算能力足够强,使用原生D3绘制流程图绝对可以的,但是,为了让大家更容易上手,避免重复造轮子,给大家推荐一个专门绘制流程图的 D3 插件 dagre-d3。 首…

idea tomcat js 汉字乱码

Run/Debug Configuiations->VM options:-Dfile.encodingUTF-8

服务 第七章

目录 1.tomcat 核心组件 2.处理请求&#xff0c;内部数据流向 3.请求处理过程 4.主要目录说明 5.tomcat 优化 6.总结 1.tomcat 核心组件 2.处理请求&#xff0c;内部数据流向 3.请求处理过程 4.主要目录说明 5.tomcat 优化 6.总结 tomcat 属于轻量级应用服务器&#xf…