iOS 打包.framework(包括第三方、图片、xib、plist文件)详细步骤及需要注意的地方...

https://www.cnblogs.com/yk123/p/9340268.html

// 加载自定义名称为Resources.bundle中对应images文件夹中的图片
// 思路:从mainbundle中获取resources.bundle
NSString *strResourcesBundle = [[NSBundle mainBundle] pathForResource:@”Resources” ofType:@”bundle”];
// 找到对应images夹下的图片
NSString *strC = [[NSBundle bundleWithPath:strResourcesBundle] pathForResource:@”C” ofType:@”png” inDirectory:@”images”];
UIImage *imgC = [UIImage imageWithContentsOfFile:strC];
[_imageCustomBundle setImage:imgC];

最近在研究如何制作自己的.framework,在网上看了好多文章,但是写的都不是很全,里面也不包括资源图片、第三方(如Masonry,AFN)和plist文件,所以只能自己动手了。下面详细介绍一下如何生带有第三方、图片、plist文件的.framework

 

NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"WSDatePickerBinder" ofType:@"bundle"];

        NSBundle *wsdatebundle = [NSBundle bundleWithPath:bundlePath];

        self = [[wsdatebundle loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] lastObject];

一、制作.framework

1.首先,我们新建工程,选择Coco Touch Framework

创建工程

2.使用CocoaPods导入Masonry和SVProgressHUD(这里以Masonry和SVProgressHUD为例),打开WQFramework.xcworkspace,可以看到我们的第三方已导入成功,接下来就要进行一些配置了。(以上都是废话,下面的才是重点!)

成功导入第三方

3.我们先创建两个类,WQClass :NSObject和WQView : UIView(我这里只是demo,在实际中可以把自己想要打包的文件都拉进来),我们在WQClass和WQView的.h中分别写一个初始化方法,并在.m中实现方法。这里我们在WQView中导入我要使用的第三方,并使用他们,我创建了两个UIImageView,并给其中一个附上了图片。并且我拉进来一个plist文件,读取并打印了它(这里是方便我们看一下打包framework时,图片和plist文件直接使用会出现什么问题)

WQView.h中初始化方法
WQView.m实现方法

4.更改参数配置:

(1)选中 Target ,选择 Build Settings ,在 Architectures 下增加 armv7s 。

增加 armv7s 

(2)Build Active Architecture Only修改为NO,否则生成的静态库就只支持当前选择设备的架构。

Build Active Architecture Only修改为NO

(3)在搜索栏搜索 Mach-O Type ,将 Mach-O Type修改为 Static Library(静态库)类型。

将 Mach-O Type修改为 Static Library

(4)选中 Target ,选择 Build Phases - Headers ,可以看出有三个选项,分别是 Public 、Private 、Project ,把需要公开给别人的 .h 文件拖到 Public 中,把不想公开的,即为隐藏的 .h 文件拖到 Project 中。

选择需要公开的头文件

5.完成上述步骤之后,在默认生成的.h文件中,我的是WQFramework.h,把所有需要暴露的.h文件都用#import 引入,记住一定要将所有需要暴露的.h文件都引入,也就是上面Headers-Public中加的所有.h文件,不然编译后生成的.framework在引用的时候会有警告。

导入所有要暴露在外的头文件

6.打包framework:分为真机和模拟器,这两个生成的framework是不一样的。这里只进行生成真机framework,个人感觉生成模拟器的.framework并没什么卵用。(如果说你需要生成一个既可以真机使用又可以模拟器使用的,那就分别生成,最后在合并在一起)。按照下图将编译的 Device 选择为真机 ,然后按下 Command + B 开始编译,编译成功后右键 Products 文件夹下的 .framework 文件,点击 Show in Finder。

生成真机.framework

 

未编译时.framework是红色的

 

编译成功.framework为黑色

重点:我这时我编译会报错,把Build Active Architecture Only修改为YES,编译就会成功,这时再切换为NO编译,还是会成功。经过总结Build Active Architecture Only为YES或者NO,导出framework后都正常使用,亲测!

7.测试打包完成的.framework,把生成的.framework导入测试项目json中,测试framework中的WQClass类和WQView类。(注意:我们在framework中使用了Masonry和SVP,所以在测试项目json中,我们需要使用cocoapods导入这两个第三方,不然会报错!)

测试framework

 

真机运行结果

可以看到,我们制作的.framework成功了!可是别高兴太早,我们在framework中使用的图片并没有显示,读取的plist文件打印也为空!接下来我们就需要处理framework中的图片和plist文件了。

二、制作bundle

1.新建项目,选择macOS ---> Bundle

创建bundle文件

2.因为Bundle默认是macOS系统的,所以我们要修改他的属性。

修改成iOS系统

3.修改Build Setting中COMBINE_HIDPI_IMAGES属性为NO。否则Bundle图片格式就会为tiff格式。

设置图片格式

4.作为资源包只需要编译就好,不需要安装相关配置,设置Skip Install的值为YES,同时删除Installation Directory的键值

设置Skip值,删除Installation Directory的键值

5.把图片拉进Bundle中,选择真机模式,command + B,右键Show in Finder,可以看到我们生成的Bundle文件。

导出Bundle

6.把Bundle文件导入到我们的framework中,我们用到图片的时候,就取Bundle中的图片来用。使用时注意,具体用法?

读取bundle资源包重的图片

7.command + B,把新生成的framework重新导入demo中,并把Bundle也导入demo,运行demo。(注意:如果demo中不导入Bundle,图片是不会显示出来的)

重新导入framework和Bundle运行程序

这时可以看到,图片可以显示出来了,说明我们的Bundle制作成功了,图片的问题我们解决了,下面要解决plist文件了。其实根据我们Bundle的制作过程,不难想到plist文件的使用原理。

三、plist文件的使用

1.其实plist文件的使用原理和图片一样,只不过图片需要制作Bundle,而plist文件不需要。把plist文件拖进framework中,重新编译framework,把重新编译的framework和plist文件都拖到demo中,这样我们就可以打印出plist文件了。

plist拖进framework中
把plist文件拖到demo,打印出数据

四、xib

如果你要打包的framework中包含xib,我们在初始化xib时要这样写?,带上你framework的名字。然后在我们的·测试demo中的Copy Bundle Resources中添加这个framework。

初始化写法
导入framework
但这个时候报了一个错:

 

错误原因很好理解就是说在nib里找不到图片,我觉得这肯定是一个低级错误,是路径的配置问题,所以就把问题定位到初始化nib文件:

单单从代码看找不出问题,单经过尝试后一下方法是可以的:

 

 


注意⚠️:

1. -ObjC:加了这个参数后,链接器就会把静态库中所有的 Objective-C 类和分类都加载到最后的可执行文件中。

2. -all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到 ld: duplicate symbol 错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到 -ObjC 失效的情况下使用 -force_load 参数。

3. -force_load:所做的事情跟 -all_load 其实是一样的,但是 -force_load 需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。

 

注意3图

 


出现错误!

今天在引入一个静态framework库时候,编译遇到了“Can't map file, errno=22 file 'xxx' for architecture arm64(armv7)”问题!

起因是我在主项目中,build setting-----》other linker flags 中-force_load了该framework库

1,找到引用项目的build setting----》build active architecture only ----》设置成NO

我原本就是no,所以结果没啥用

2,最后尝试了这一种办法

将主项目中other linker flages 中的-force_load "XXX.framework"改成“-force_load "XXX.framework/XXX”其中XXX是静态库名。

 

 

 

 

iOS - 制作Bundle资源文件包以及正确访问

https://blog.csdn.net/yuge486/article/details/79580339

一、创建Bundle项目

 

 

二、在bundle资源包中添加图片

 

 

方式一:使用Asset管理图片

在Xcode自带的Assets里面,可以自动识别图片是二倍屏还是三倍屏,图片名称以@2x,@3x为后缀,拖到Assets文件里会自动识别位置

1>创建Asset文件

 

 

2>拖入对应的图片

 

方式二:

创建images文件夹,如图所示,再拖入对应后缀名的图片

 

 

三、生成Bundle包

 

Command + B后生成Bundle包,点击Products里面的bundle文件

 

四、集成到项目中

将Bundle资源包放到项目的任意(或指定)的文件夹下

 

 

五、代码调用Bundle包的图片资源(写在UIImage的extension里):

 

1>方式一加载图片(使用Asset管理图片时),使用以下方法:

 

/// 从Bundle中加载图片

    ///

    /// - Parameter filename: 图片名称

    /// - Returns: 返回UIImage对象

   class func bundleImageNamed(_ filename: String) -> UIImage? {

    let path = "\(Bundle.main.resourcePath ?? "YourBundleName.bundle")"

    return UIImage(named: filename, in: Bundle(path: path), compatibleWith: nil)

    }

2>方式二加载图片

 

生成的资源包右键查看包内容,可以看到图片的路径,如图所示

 

 

 

代码调用如下

 

/// 从Bundle中加载图片

    ///

    /// - Parameter filename: 图片名称

    /// - Returns: 返回UIImage对象

   class func bundleImageNamed(_ filename: String) -> UIImage? {

    let pathName = "YourBundleName.bundle/Contents/Resources/\(filename)"

    let url = "\(Bundle.main.resourcePath ?? "")/\(pathName)"

    return UIImage(contentsOfFile: url )

    }

--------------------- 

作者:yuge486 

来源:CSDN 

原文:https://blog.csdn.net/yuge486/article/details/79580339 

版权声明:本文为博主原创文章,转载请附上博文链接!

转载于:https://www.cnblogs.com/sundaysgarden/p/10762768.html

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

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

相关文章

MySQL中innodb_page_cleaners详解

innodb_page_cleaners是MySQL中的刷脏线程个数,它的值等于innodb_buffer_pool_instances的值,如果innodb_page_cleaners的值大于innodb_buffer_pool_instances的值,那么自动的将innodb_page_cleaners调整为与innodb_buffer_pool_instances的值…

uiimagepickerviewcontroller

if(0buttonIndex) { if (![UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) { UIAlertView *alert [[UIAlertView alloc] initWithTitle:"" message:"当前设备不支持拍照功能" delegate:nil cancelButtonTitl…

关于CString的=操作符

检查自已的代码时,发现一个比较弱智的错误,是关于转码的,和CString的操作符有关。 为了能简单重现,我模拟了一下代码: //未有UNICODE或_UNICODE定义 USES_CONVERSION; CString sTest(_T("test中文")); s…

分布式锁的几种使用方式(redis、zookeeper、数据库)

三种方案的比较 从理解的难易程度角度(从低到高) 数据库 > 缓存 > Zookeeper从实现的复杂性角度(从低到高) Zookeeper > 缓存 > 数据库从性能角度(从高到低) 缓存 > Zookeeper > 数据库从…

SQL优化准则

1. 在长时间运行的查询和短查询中使用事务 如果预期有一个长时间运行的查询,并且有大量的数据输出时,开发者就应该在BEGIN TRAN 和END TRAN之间使用事务。 这样事务会在缓冲区缓存为独立事务,并会被分配特定内存,以此来提高处理…

C语言库函数--strstr()

原型&#xff1a;extern char *strstr(const char *str1, const char *str2); 需要包含的头文件&#xff1a;#include <string.h> 作用&#xff1a;用于判断字符串str2在字符串str1中第一次出现的位置。如果没有找到则返回NULL&#xff0c;找到了则返回str1中的位置。 …

《离散数学》双语专业词汇表 名词术语中英文索引

《离散数学》双语专业词汇表 set&#xff1a;集合 subset&#xff1a;子集 element, member&#xff1a;成员&#xff0c;元素 well-defined&#xff1a; 良定&#xff0c;完全确定 brace&#xff1a;花括号 representation&#xff1a;表示 sensible&#xff1a; 有意义的 rat…

less is more,so 只记 less

less 文件名 1.Enter键  &#xff1a;向下翻一行 2.空格键   &#xff1a;向下翻一屏 3.j键    &#xff1a;想下翻一行 4.k键    &#xff1a;向上翻一行 5.f键    &#xff1a;向下翻一屏 6.b键     &#xff1a; 向上翻一屏 7.d键    &#xff1a;向…

预祝大家2011农历新年快乐,宏“兔”大展,心想事成~

预祝大家2011农历新年快乐&#xff0c;宏“兔”大展&#xff0c;心想事成&#xff5e; 又是一年新年到&#xff0c;预祝大家2011农历新年快乐&#xff0c;宏“兔”大展&#xff0c;心想事成&#xff5e; _____________________________________________________ 以下是附带的……

MySQL中的表压缩功能

MySQL版本&#xff1a;8.0.22 os&#xff1a;linux ubuntu 语言&#xff1a;c、c 在MySQL中支持3种类型的表压缩&#xff0c;依次为&#xff1a;传统压缩、TPC压缩、字典压缩。 第一种&#xff1a;传统压缩 传统的表压缩方式是在MySQL5.0.7之前使用的&#xff0c;现在已经废…

net core体系-web应用程序-4asp.net core2.0 项目实战(1)-11项目日志解决方案

本文目录1. Net下日志记录2. NLog的使用 2.1 添加nuget引用NLog.Web.AspNetCore 2.2 配置文件设置 2.3 依赖配置及调用 2.4 日志类型介绍 2.5 产生的日志文件3. 基于Microsoft.Extensions.Logging封装 3.1 添加引用Microsoft.Extensions.Logging 3.2 实现…

strcasecmp()--忽略大小写比较字符串

strcasecmp()的功能是&#xff1a;忽略大小写比较字符串 头文件 #include <strings.h> 函数原型&#xff1a;int strcasecmp(const char *s1, const char *s2); 函数功能: 用来比较参数s1和s2字符串&#xff0c;比较时会自动忽略大小写的差异。 返回值: 若参数字符串…

NDK 获取android的imei和serial number

1&#xff0c;获取imei int setAndroidDeviceID(JNIEnv *env, jobject obj,jobject mContext) {if(mContext 0){return -1;}jclass cls_context (*env)->FindClass(env, "android/content/Context");if(cls_context 0){return -1;}jmethodID getSystemService …

《JS高级程序设计》PART3.对象基础

3.2对象应用 对象废除&#xff1a;如果一个对象有2个及以上引用&#xff0c;则要正确的废除该对象&#xff0c;必须将其所有引用都设置为null。 js和java一样&#xff0c;有垃圾回收机制&#xff0c;会自动收回已无引用指向的对象。 早绑定和晚绑定 绑定&#xff1a;把对象的…

python迭代-如何对迭代器做切片操作

如何对迭代器做切片操作 问题举例 读取某个文件内容的100~300行内容&#xff0c;我们是否可以使用 类似列表切片的方式得到一个100~300行文件内容的生成器 分析 列表的切片操作其实是在重载方法__getItem__方法 可以通过file.readlines()后再做切片&#xff0c;内存会加载整个文…

如何让linux服务器同步互联网时间

今天在工作中需要搭建一个数据库集群s1&#xff0c;需要将节点A、节点B和节点C都加入集群&#xff0c;先在A节点上创建集群&#xff0c;然后将B和C节点加入到集群&#xff0c;但是在B和C加入到集群之前&#xff0c;会判断B与A、C与A的时间戳是不是在设置的2s~5s内&#xff0c;如…

Conda常见命令

Anaconda,Miniconda,Conda,Pip的区别&#xff1a; Anaconda&#xff1a;用于科学计算的python发行版&#xff0c;里面预装好了conda&#xff0c;某个版本的python&#xff0c;众多packages,科学计算工具等。Anaconda利用工具/命令conda来进行package和environment的管理&#x…

MySQL一张innodb表列个数的限制和engine的选择

在MySQL innodb存储引擎中&#xff0c;一张表中列的个数最大为4096。 其中在MySQL中&#xff0c;创建表时可以任意指定engine的类型&#xff0c;但是&#xff0c;考虑到join、union、union all等复杂的场景时&#xff0c;尽量每张表都用统一的engine。

Hibernate读书笔记

伟大的信息管理与信息系统专业&#xff0c;万恶的信息管理与信息系统专业。说这句话我是有根据的&#xff1a;因为这个专业雄心勃勃的想把自己的子弟培养成全面发展的人才但是结果则不然。两方面的原因&#xff1a;一部分在学生&#xff0c;但是一部分在这个专业。让我极其郁闷…

基于报文地址的策略路由配置示例

【实验拓扑】本文实验采用的交换机是H3C模拟器&#xff0c;下载地址如下&#xff1a; http://forum.h3c.com/forum.php? modviewthread&tid109740&highlightH3C%E6%A8%A1%E6% 8B%9F%E5%99%A8 有兴趣的朋 友可以在论坛上去下载 【组网需求】普通的报文转发是依据报文的…