参考:
iOS开发之静态库.a的制作教程
静态库和动态库
静态库和动态库的存在形式
静态库: .a 和 .framework
动态库: .dylib 和 .framework
静态库和动态库在使用上的区别
静态库:链接时,静态库会被完整地复制到可执行文件中, 被多次使用就有多份冗余拷贝 (左图所示)
动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存
如果想让一个 .a 文件能同时用在真机和模拟器上,需要进行合并
在终端输入指令
lipo -create Debug-iphoneos/libMJRefresh.a Debug-iphonesimulator/libMJRefresh.a -output libMJRefresh.a
.a 文件的体积(一般情况下)
通过 lipo –info libMJRefresh.a 可以查看 .a 的类型(模拟器还是真机)
在iOS中创建静态库
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# Step 1. Build Device and Simulator versions
xcodebuild -target ImageFilters ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target ImageFilters -configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html
代码并不十分复杂,它是这样工作的:
UNIVERSAL_OUTPUTFOLDER 包括了通用二进制包将要被存放的文件夹:“Debug-universal”
Step 1. 第2行执行了xcodebuild并命令它构建ARM架构的二进制文件。(你可以看到这行中的-sdk iphoneos参数)
下一行再次执行了xcodebuild命令并在另一个文件夹中构建了一个针对Inter架构的iPhone模拟器的二进制文件,在这里关键参数是-sdk iphonesimulator -arch i386。(如果感兴趣,你可以在
man page了解更多关于xcodebuild的资料)
Step 2. 现在已经有了2个.a文件分别对应两个架构。执行lipo -create,用它们创建出一个通用二进制。
最后一行的作用是复制头文件到通用构建文件夹的外层。(用cp命令)
有两种办法可以将静态库引入到工程中:
方法 1: 直接引用头文件和库二进制文件(.a)
方法 2: 将库工程作为子项目
方法 1: 头文件和库二进制文件
注意: 标准的Unix引入惯例是一个include文件夹,用来存放头文件,一个lib文件夹用来存放库文件(.a)。这种文件夹结构这是一种惯例,并不强制。你并不需要一定遵从这种结构或者复制文件到工程文件夹中。在你自己的应用中,你可以任意选择头文件和库文件的位置,只要随后在Xcode工程中设置了适当的路径。
双击Header Search Paths项,弹出一个浮动窗口,点击+按钮,输入:
- $SOURCE_ROOT/include
$SOURCE_ROOT是一个Xcode环境变量,指向工程根文件夹。
1、创建一个工程,或者在原有的工程上进行。不在列举。2、在原有工程上添加一个静态库
2.1、选择OS X 的Bundle。因为Xcode6.1中iOS里没有Bundle。
2.2、修改Bundle的属性,一是让他能用在iOS上。二是改变Bundle成为Framework选中要修改的Bundle
2.3、Target:并选择 Build Settings -> Architectures -> Base SDK 改为Latest iOS(ios 8.1)
2.4、Target:在 Deployment 下,将 “Mac OS X Deployment Target”改成”Compiler Default”,将 “Targeted Device Family”改成”iPhone/iPad”,根据自己的需要改。如果你只想在iPhone上用,那选iPhone就行将 “iOS Deployment Target”,改成 “iOS 7.0”:也就是说这个静态库支持7.0以上版本。
2.5、Target:在 Linking 下,将 “Dead Code Stripping” 改为 “NO”,将 “Link with Standard Libraries” 改为 “NO”,将 “Mac-O Type” 改为 “Relocatable Object File”:
2.6、Target:Packaging 中,将 “Wrapper Extention” 改为“framework”:
2.6、Target:返回Info 标签。将 “Bundle OS Type Code” 改为 “FMWK”(Framework )
2.7、Target:返回Build Phases 标签。加入Copy Headers,后边会用到。
10、关于第三方库找不到文件的提示错误。简单补充下吧,别走弯路。
首先你要确定这个错误产生的原因:大致分两种,
一:你做的项目缺失文件,百度下,加入就解决了;
二:你引入的第三方框架发生找不到文件错误:这样的结果分两种:
二、一:开发第三方框架的程序人员没有做好自己的框架。尤其是在生成框架的时候,没有设置好自身属性。导致使用者用的时候出现找不到文件错误,最后迫使使用者不得不去改自己的工程配置。
二、二:你在引入第三方框架的时候,少引用了文件。
好了,你分析完后就好办了,我们做的这个静态库没有设置自己的兼容属性,所以就照成了这种错误。在iPad Retina的模拟器上跑就正常,换成其他的模拟设备就报错。所以改下其属性就能解决。
Target: -> Build Settings -> Architectures -> Build Active Architecture Only 全改成NO;
在我们生成静态库的时候,我们选择的是iPad Retina。也就是说这个静态库在引用的时候,必须也是iPad Retina。否则Xcode编译器会找不到文件所在。
大家可以实验下,在iPad Retina下导出静态库,在其他工程使用的时候,如果用iPad Retina跑就没有错误。如果选择其他设备就会提示找不到文件。
兼容全部设备解决方法:改下静态库的兼容属性。Target: -> Build Settings -> Architectures -> Build Active Architecture Only 全改成NO;
Build Active Architecture Only
这个属性设置为yes,是为了debug的时候编译速度更快,它只编译当前的architecture版本,所以会报错编译不到文件,出错("_OBJC_CLASS_$_xxxxxx", referenced from:)
而设置为no时,会编译所有的版本,这样就解决编译出错的问题了。
这个是设备对应的architecture:
armv6:iPhone 2G/3G,iPod 1G/2G
armv7:iPhone 3GS/4/4s,iPod 3G/4G,iPad 1G/2G/3G
armv7s:iPhone5, iPod5
arm64:iPhone5s
编译出的版本是向下兼容的,比如你设置此值为yes,用iphone4编译出来的是armv7版本的,iphone5也可以运行,但是armv6的设备就不能运行。
真机版和模拟器版的库合并解决方法:在framework文件夹下,你会看到一个白板文件,这个文件名和的的framework静态库名相同,只是没有后缀名。 这个文件在被引入到其他工程时候是看不见的。只有在Show In Finder下能看到。
打开终端,输入命令:中文换成你的真实目录。
lipo -create “……真机/目录/那个白板文件“ "……/模拟器/目录/那个白板文件" -output “…..另保存的/目录/文件”
合并好的新文件,覆盖掉原来的framework中的文件即可。这个framework就会支持所有设备和真机、模拟器全部版本。
其实这个方法就是用*.a文件的合并方法。在framework一样有效。framework中的白板文件就好像*.a文件一样。
9、关于xib的引用。同样根上边创建framework的方法一样,只是设置不同。我加了一个名字为:Resource.bundle静态资源文件。这个样子:
Target:并选择 Build Settings -> Architectures -> Base SDK 改为Latest iOS(ios 8.1)Target:在 Deployment 下,Target:将 “Mac OS X Deployment Target”改为”Compiler Default”,Target:将 “Targeted Device Family”改”iPhone/iPad”,Target:将 “iOS Deployment Target”,改为 “iOS 7.0”:
iOS开发——创建你自己的Framework
什么是Framework?
Framework是资源的集合,将静态库和其头文件包含到一个结构中,让Xcode可以方便地把它纳入到你的项目中。
在OS X上,可能会创建一个动态连接(Dynamically Linked)的framework。通过动态连接,framework可以更新,不需要应用重新连接。在运行时,库中代码的一份拷贝被分享出来,整个工程都可以使用它,因此,这样减少了内存消耗,提高了系统的性能。正如你看到的,这是一个功能强大的特性。
在iOS上,你不能用这种方式添加为系统添加自定义的framework,因此仅有的动态链接的framework只能是Apple提供的那些。(编者注:在iOS 8中已加入此特性,开发者可以使用第三方的动态框架)
然而,这并不意味着framework对于iOS而言是无关紧要的,静态连接的framework依然可以打包代码,使其在不同的应用中复用。
由于framework本质上是静态库的“一站式采购点”,因此在本篇教程中你所做的第一件事就是创建并使用静态库。当跟着教程走到如何创建framework时,你就能明白你所做的一切了,整体思路也不会那么烟雾缭绕了。
Note:显然,所有包含在你的公共头文件中的头文件必须是对外公开的,这一点非常重要。否则,开发者在使用你的库时会得到编译错误。如果Xcode在读取公共头文件时不能读到你忘记设为public的头文件,这实在是太令人沮丧了。
默认情况下,有两种resolutions的图片可以产生一些有趣的现象。例如,当你导入一个retina @2x版本的图片时,普通版的和Retina版的将会合并成一个多resolution的TIFF(标签图像文件格式,Tagged Image File Format)。这不是一件好事。搜索hidpi将COMBINE_HIDPI_IMAGES设置为NO。
动态库,在使用的时候需要额外加一个步骤,要把Framework同时添加到‘Embedded Binaries’中。
# Sets the target folders and the final framework product.
# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
# 例如: FMK_NAME = "MyFramework"
FMK_NAME=${PROJECT_NAME}
# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework
# Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
# -configuration ${CONFIGURATION}
# Clean and Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build
# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"
rm -r "${WRK_DIR}"
open "${INSTALL_DIR}"
分享到:
相关推荐
1、在ios目录下新建bundle目录。后面编译打包离线资源,也会生成bundle目录,提前建,是为了防止某些情况下报错。 2、进行编译,离线打包资源。命令如下: react-native bundle --entry-file index.js //entry-...
source ~/.vim/bundle/fuzzyfinder/conf.vim "NERD_commenter.vim source ~/.vim/bundle/nerdcommenter/conf.vim "单独切换打开NERD_tree source ~/.vim/bundle/nerdtree/conf.vim "neocomplcache.vim source ~/....
2、vimfiles 新建bundle目录 3、下载插件(https://github.com/gmarik/vundle)将vundle整个目录丢进bundle目录 4、下面见证奇迹的时刻到了 命令行输入:BundleInstall 回车 哦了 此配置包涵一下插件: Bundle '...
本篇文章将详细探讨iOS SDK中的关键组成部分,包括.framework静态库、.bundle资源文件以及脚本打包SDK和.bundle的相关知识。 首先,我们来看.framework静态库。.framework是iOS中的一种库文件格式,它包含了一个或...
在iOS开发中,Bundle是一个非常重要的概念,它包含了应用程序运行所需的所有资源,如图片、音频文件、本地化字符串、故事板、XIB文件等。本文将深入探讨如何使用名为"SimPholders2.app"的工具来查看iOS应用的bundle...
ios中bundle的使用将图片文件夹的后缀改名为:xxx.bundleVC获得bundle中的资源NSString * bundlePath = [[ NSB
在iOS开发中,Bundle是应用程序资源的容器,它包含了图片、音频、本地化字符串、故事板等非代码文件。本文将深入探讨如何打包Bundle以及如何在应用中加载这些Bundle,同时也会涉及Bundle的安全性,尤其是加密策略。...
cd ~/.vim/bundle/YouCompleteMe git submodule update --init --recursive cd ~/.vim/bundle/YouCompleteMe ./install.py --clang-completer apt-get install cmake apt-get install ack apt-get install ctags ...
事情 这些说明会安装vim资料,以供我使用。 安装 git clone ...cd ~/.vim/bundle/YouCompleteMe python3 install.py --clangd-completer 我正在使用的插件 /VundleVim/Vundle.vim.git /command-
1. WPS Office iOS SDK 的 Bundle 名称为 KingsoftOfficeSDK.bundle。 2. 在 Xcode 中,可以通过添加 KingsoftOfficeSDK.bundle 来使用 WPS Office iOS SDK。 九、WPS Office iOS SDK Config 1. WPS Office iOS ...
android adt-bundle-windows-x86_64(有双平台资源) 有5.1 SDK api22 和最新的6.0 SDK api 23,因文件较多,下载后解压到对应目录即可,内附百度网盘链接和提取码
ca-bundle.crt证书
封装 iOS 系统常用接口,存取bundle中的资源,读取本地化文本,执行选择器和 UserDefaults 的相关操作,调用通知中心的相关操作等。 软件开发设计:PHP、QT、应用软件开发、系统软件开发、移动应用开发、网站开发C++...
15年6月更新,完整的repo-project,完美解决fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle 错误,绕开GFW,详细请参考我的博客《完美解决repo init 错误 fatal: Cannot get ...
在iOS开发中,有时我们需要获取用户设备上安装的所有应用程序的相关信息,例如应用的bundle ID、图标(icon)、名称等。这个任务通常对于系统分析、数据分析或者个性化推荐等场景很有用。在提供的标题和描述中,提到...
### iOS App提交/上传到商店流程详解 #### 一、准备工作 在开始向App Store提交应用之前,确保已经完成了以下准备工作: 1. **苹果开发者账号**:拥有有效的苹果开发者账号是进行任何操作的前提条件。 2. **开发...
react-native bundle --entry-file ./index.js --bundle-output ./ios/bundle/index.ios.jsbundle --platform ios --assets-dest ./ios/bundle --dev false ``` 步骤 4:导入 JSBundle 文件 把生成的 JSBundle ...
3、连接手机,在我的电脑里打开iTools-“工具箱”-“文件管理”,把附件里的文件(除了教程图片)拖到“越狱系统”里的“/var/mobile/Library/Carrier Bundle.bundle”; 4、重启手机会发现正常登录到3G或4G网络...
iOS采用的是基于沙盒的安全机制,每个应用程序都有自己的沙盒环境,包含Documents、Library、tmp和Bundle等目录,用于存储和读取数据。开发者需要了解如何在这些目录间进行操作,同时遵循苹果的App Store审核指南。 ...
在Android应用开发中,Intent和Bundle是两种非常重要的数据传递工具。它们都在应用程序组件之间起着桥梁的作用,但各自有着不同的特性和应用场景。本篇文章将深入探讨“测试Android中Intent传值与Bundle传值的不同”...