iOS |知识点整理(14)

1,277 阅读18分钟

延续上一篇iOS |知识点整理(13)

iOS | UIBezierPath 圆角展示不全的问题及解决方案

sg.jianshu.io/p/f936bb30f…

默认radius最多显示宽高的一半,但是可以通过移动mask的y来使radius显示更多,注意mask的layer的高度>= 2*radius 关于Module

  1. 使用模块使得原来的#import文件包含变成了语义上的导入. semantic import. 当新建一个framework,会自动创建一个和framework同名的头文件,而且module机制是默认开启的, 在打包之后,会生成一个module.modulemap文件.

  2. 一旦我在xcode中启用的module机制,那么程序中原来的#import,会被自动转化为@import. 一个工程的module机制是默认打开的,使得我们对于系统的framework只要import一下,就可以了,而不用再手动添加依赖库了

37BEE58E-3FF4-4631-BC7D-29BE8205CD3A.png

  1. 模块可以编译一次,然后在各处使用.可以节省编译时间,不再需要pch机制来编译文件了.使用PCH,无法确定当前模块有哪些依赖,而且也使得代码变得不好移植.

  2. 可以模块内部工程中使用 #import moduleName/header.h来引用自己的头文件. 可以把一个文件夹抽象成一个模块,通过module.moduleMap文件来做到. github.com/drekka/Alch…

  3. 可以通过在工程中自定义module.modulemap, 在测试工程中使用@import

github.com/drekka/Alch… ref: Modular framework, creating and using them

  1. 使用模块.
Replace #import <Cocoa/Cocoa.h> with @import Cocoa;
You can also import just one header with this notation:
@import iAd.ADBannerView;

The submodules autocomplete for you in Xcode.

stackoverflow.com/questions/1…

关于Module机制的优缺点

Semantic import

Modules improve access to the API of software libraries by replacing the textual preprocessor inclusion model with a more robust, more efficient semantic model. From the user’s perspective, the code looks only slightly different, because one uses an import declaration rather than a #include preprocessor directive:

import std.io; // pseudo-code; see below for syntax discussion

However, this module import behaves quite differently from the corresponding #include <stdio.h>: when the compiler sees the module import above, it loads a binary representation of the std.io module and makes its API available to the application directly. Preprocessor definitions that precede the import declaration have no impact on the API provided by std.io, because the module itself was compiled as a separate, standalone module. Additionally, any linker flags required to use the std.io module will automatically be provided when the module is imported [1] This semantic import model addresses many of the problems of the preprocessor inclusion model:

  • Compile-time scalability: The std.io module is only compiled once, and importing the module into a translation unit is a constant-time operation (independent of module system). Thus, the API of each software library is only parsed once, reducing the M x N compilation problem to an M + N problem.
  • Fragility: Each module is parsed as a standalone entity, so it has a consistent preprocessor environment. This completely eliminates the need for __underscored names and similarly defensive tricks. Moreover, the current preprocessor definitions when an import declaration is encountered are ignored, so one software library can not affect how another software library is compiled, eliminating include-order dependencies.
  • Tool confusion: Modules describe the API of software libraries, and tools can reason about and present a module as a representation of that API. Because modules can only be built standalone, tools can rely on the module definition to ensure that they get the complete API for the library. Moreover, modules can specify which languages they work with, so, e.g., one can not accidentally attempt to load a C++ module into a C program. Problems modules do not solve

Many programming languages have a module or package system, and because of the variety of features provided by these languages it is important to define what modules do not do. In particular, all of the following are considered out-of-scope for modules:

  • Rewrite the world’s code: It is not realistic to require applications or software libraries to make drastic or non-backward-compatible changes, nor is it feasible to completely eliminate headers. Modules must interoperate with existing software libraries and allow a gradual transition.
  • Versioning: Modules have no notion of version information. Programmers must still rely on the existing versioning mechanisms of the underlying language (if any exist) to version software libraries.
  • Namespaces: Unlike in some languages, modules do not imply any notion of namespaces. Thus, a struct declared in one module will still conflict with a struct of the same name declared in a different module, just as they would if declared in two different headers. This aspect is important for backward compatibility, because (for example) the mangled names of entities in software libraries must not change when introducing modules.
  • Binary distribution of modules: Headers (particularly C++ headers) expose the full complexity of the language. Maintaining a stable binary module format across architectures, compiler versions, and compiler vendors is technically infeasible.

WWDC: From the WWDC slides:

* Imports complete semantic description of a framework
* Doesn't need to parse the headers
* Better way to import a framework’s interface
* Loads binary representation
* More flexible than precompiled headers
* Immune to effects of local macro definitions (e.g. #define readonly 0x01)
* Enabled for new projects by default

ref:clang.llvm.org/docs/Module…

Swift中使用模块机制来使用C库

Getting Started Using C Libraries from Swift
Creating Objective-C modules
Private module map for a framework
Importing CommonCrypto in a Swift framework
github:

github.com/onmyway133/…

github.com/tiger8888/J…

关于模块和PCH

For modern iOS and OS X, people should be using Modules. This is enabled by default for new projects, and importing/inclusion is accomplished using @import. Modules allow the compiler to create an intermediate representation of the contents of a module (e.g. a framework's headers). Much like a PCH, this intermediate representation may be shared across multiple translations. But modules take this one step further because a module is not necessarily target specific, and their declarations need not be localized (to a *.pch). This representation can save you a ton redundant compiler work.

Using modules, you do not need a PCH, and you probably should just do away with them entirely -- in favor of using @import local to the dependency. In that case, a PCH is only saving you from typing inclusions local to dependencies (which IMO you should be doing anyway).

ref:stackoverflow.com/questions/2…

Xcode Precompile Prefix Header浅析

1.如果要使用prefix header,首先在工程中添加pch文件,然后在build setting中进行如下设置:

205E38E7-D874-4891-80E5-CA103D3C48EF.png

2.使用pch文件有两个好外:一是节省了头文件的编译时间 二是让所有的文件都可以直接使用pch文件中的头文件.

3.xcode8默认是关掉prefix header的. 个人理解,Xcode 6去掉Precompile Prefix Header的主要原因在于: (1)去掉自动导入的系统框架类库的头文件,可以提高原文件的复用性,便于迁移。 (2)一个肥胖无比的Prefix Header会大大增加Build Time。

4.xcode8 的module机制默认是开启的,

5.PCH文件弊端:

Xcode Precompiled Headers: 4 Ways They Cripple Your Code

ref:Xcode Precompile Prefix Header浅析 - Jymn_Chen - 博客频道 - CSDN.NET

关于Group和文件夹的区别

NSBundle的使用,注意mainBundle和Custom Bundle的区别 - 静候良机 - 博客园

Xcode中的group中的文件在打包之后,会被放到根目录. 而放在文件夹中的文件,还会放在文件夹中. 那么他们的引用方式,也就会不同了.

显示xcode中的环境变量等信息

//显示工程的配置信息,环境变量等
xcodebuild -project TESTCordovaLib.xcodeproj -target "TESTCordovaLib" -showBuildSettings


//显示workspace的相关信息,比如Scheme信息等
xcrun xcodebuild -list -workspace HealthMonitorApp.xcworkspace

//显示workspace中pod工程的相关信息 
xcrun xcodebuild -showBuildSettings -workspace HealthMonitorApp.xcworkspace -scheme Pods-HealthMonitorApp

一些常用的环境变量:
假设一个 Project 的路径是 XXX/ProjectX。
$SRCROOT:XXX/ProjectX

ref: Xcode Build Settings - Products Path

Xcode出现下面错误的一个解决方法

4C949602-CA2D-40A0-AD72-54E368E19BF4.png

I had similar issue ad problem was there was an info.plist file in one of the folder in framework that i downloaded from GitHub , deleting it fixed the issue.

实际上引起上面的问题的有很多种原因,上面的只是其中的一种解决方法.

copypng emitted errors but did not return a nonzero exit code to indicate failure

Build Phases -> Copy Bundle Resources, Any fileName is red color?

Or

Convert Logo Retina.png or Create it again, maybe it's an encoding\format issue.

Or

Rename "Logo Retina.png" to "LogoRetina.png".

Or It also happens when you have multiple images with the same name in TARGET->Build Phases->Copy Bundle Resources. 有文件名相同的图片,删除掉多余的图片即可

XCode 利用正则表达式查找替换字符

要将[UIColor hx_colorWithHexRGBAString:@"#000000"] 这样的字符串替换为自定的宏。 如HEXCOLOR(0x000000)

在XCode Replace 中选择 Replace\Regular Expression, 填写相应的正则如

\[UIColor hx_colorWithHexRGBAString:@\"#(.*)\"\]
替换为 HEXCOLOR(0x$1)

$1 就是正则匹配的字符。

XCode 使用XConfig来配置多URL

1.在工程中建立相应的Config

91801459-5E4C-4361-83F8-087430199A32.png

2.在build setting当中的PreProcessors Macro当中根据不同的config,建立不同的宏 在User-Defined添加不同的宏定义. 然后在工程的global头文件当中:

#ifdef SERVERKIND_DEMO
//演示环境    Demo
#define    kServerUrl    @"http://api.demo.lifesea.com/"
#elif SERVERKIND_EXHIBITION
//828展会环境   Exhibition
#define    kServerUrl    @"http://172.16.105.222:8006/"
#endif

3.在target的Info中设置对User-Defined的引用,如Bundle Display Name等

4.最后在XCode的Scheme当中添加Scheme,在run选项中的Build Configuration选择相应的config. 做到Scheme和Config一一对应. 即可. 以后在运行工程的时候,选择相应的Scheme就可以了.

[000]XCConfig的用法 XCConfig的用法

打开安装在模拟器中的APP Document Folder目录:

Set and hit a breakpoint in the app, and write the following in the console:

po NSHomeDirectory()

Then in Finder hit CMD+G, paste the path returned above and hit enter.

或者下面的方法也可以:

Open up Terminal.app and run:

xcrun simctl get_app_container booted [app identifier]

You can even setup an alias to change to the directory, like:

alias cdmyapp='cd $(xcrun simctl get_app_container booted com.mycompany.myapp)'

ref:stackoverflow.com/questions/3…

让Xcode8继续使用原来的插件的一种方法.

  1. 编译 MakeXcodeGr8Again 并且导出其 product (关于 MakeXcodeGr8Again,下文会详细说到)。

  2. 退出 Xcode8,同时运行刚刚导出的 MakeXcodeGr8Again,将 Xcode8 拖入其中,等待一段时间(3~10分钟)。

  3. 等菊花转完后,应用程序文件夹下会生成一个 XcodeGr8 的应用,运行命令 sudo xcode-select -s /Applications/XcodeGr8.app/Contents/Developer 将 Xcode 开发路径指向刚生成的 XcodeGr8。这时验证一下生成的XcodeGr8可不可以正常运行. 如果正常删除到原来的Xcode.app. 将刚生成的 XcodeGr8改名为Xcode.app ,然后再运行sudo xcode-select -s /Applications/Xcode.app/Contents/Developer.

然后开始安装插件,插件安装在 /Users/taivex2/Library/Application Support/Developer/Shared/Xcode/Plug-ins目录里面.

  1. 既然 Xcode8 的签名已被移除,那么就可以继续使用上面的修复插件失效代码。代码如下:

find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist -maxdepth 3 | xargs -I{} defaults write {} DVTPlugInCompatibilityUUIDs -array-add defaults read /Applications/Xcode.app/Contents/Info.plist DVTPlugInCompatibilityUUID

ref:medium.com/@vong9262/%…

关于IOS Framework的codesign

From reading the linked thread on the Carthage repo it seems relatively simple. If you are distributing the binary framework you need to code sign it and if you are distributing the source via carthage or cocoa pods you do not as those tools take care of this via different methods. The reason you need to code sign it when you distribute the binary framework is that Xcode won't produce a framework binary without code signing it. If you attempt to not code sign the binary framework you get this error:

CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1' It doesn't matter which identity you code sign the framework with (iPhone Developer or iPhone Distribution) because, as you point out, the framework will be re-codesigned with the "code sign on copy" setting. This means that your framework will be re-codesigned by the appropriate certificate from the framework consumer's developer profile when your framework is copied into their application. This means there will be no issues with the App Store as it will only see the final code signature from the framework consumer.

In the end of the day, you might as well code sign your .framework binary as you don't want to have to maintain an exotic build process, and as Xcode will only output signed frameworks you shouldn't move too far away from the defaults. It doesn't really matter anyway because the end consumer will be re-signing it.

ref:stackoverflow.com/questions/3…

含有simulator slice的framework无法提交到app store github.com/lionheart/o…

关于IOS Framework

1.如果想要Framework可以以module方式被引用,那么在framework工程中:

BD54B983-E5E1-40BD-8D27-5A0CD108C785.png

那么在生成的framework中就会生成,module.modulemap文件:

1174F83A-0EDF-4D8B-91E7-333246131026.png

2.关于swift中的模块化

https://github.com/drekka/Alchemic
Creating Objective-C modules
Wrapping a C Library in a Swift Framework · Colin Drake

3.framework制作的详细过程: github.com/tiger8888/i…

4.关于资源的管理,可以添加一个bundle target,设置好这后,将它拖动到framework target中copy bundle resource中去.

demo:https://github.com/tiger8888/iOS-Framework

16264684-04B3-4AD4-AADB-9C9DF250836B.png

5.生成通用的framework,可以使用如下脚本 Xcode Library Universal Shell Script

关于IOS Framework制作与cocopods

  1. YohunlUtilsLib framework工程的podfile如下.
 platform :ios, '7.0'
   inhibit_all_warnings!

  target 'YohunlUtilsLib' do
        pod 'AFNetworking'
  end

  target 'YohunlUtilsLibTests' do
  end

那么最生成YohunlUtilsLib.framework中并没有包含AFNetworking库的内容, 所以 当我们把我们生成的YohunlUtilsLib.framework给别人使用过的时候,别人自己要在项目中添加 AFNetworking,否则会提示找不到的错误.

cocoapods应用第一部分-xcode创建.framework相关 - yohunl的专栏 - 博客频道 - CSDN.NET3

iOS开发 .framework的Optional(弱引用)和Required(强引用)区别

强引用(Required)的framework是一定会被加载到内存的,但是弱引用(Optional)的framework只在需要时才会被载入内存,这对于比较大的framework来说,在最初加载的时候会省很多时间。

简单解释一下,有一些库如Social.framework 和 AdSupport.framework,是在iOS6之后才被引入的,还有一些更新了新特性的只能在iOS6+上可用。当你添加一个framework到你的工程里,他们被默认强引用(Required),然而,当你最终把程序配置在运行5.0的设备上时,你会发现它通不过最户的加载,原因就在于这些库是不被iOS5.0支持的,就需要我们把这些库的引用改为Optional.

14AB7729-DC57-4BEF-8D10-07B32AD6D998.png

其次,如果你遇见了这个错误:duld:Library not found………………说明你有不应该强引用的可存在

2.链接命令

3FA8CB5F-9772-415C-AC53-D7E6A98372DC.png

If you'd want to weak-link it, use -weak_framework PassKit ,这个错误报告里都会指明有哪些库需要弱引用。

ref:stackoverflow.com/questions/1…

xcode6 framework missing submodule xxx 警告

从xcode6开始,iOS可以直接创建生成framework了

如:
创建 framework 项目,TFKit.framework
则 会自动生成TFKit.h
然后我们再添加一些自已的类,并对外提供 TFA.h,TFB.h
那么需要先在 TFKit.h 里面
#import <TFKit/TFA.h>
#import <TFKit/TFB.h>
最后在build 生成 TFKit.framework使用时,

直接使用 
#import <TFKit/TFKit.h> 即可
关于Bundle Target的创建和使用

ref: 创建和使用bundle target

1.建立完bundle target之后,前往Build Settings设置参数

"Base SDK" 设置为 “IOS Latest SDK" (Xcode 6.3.2为例)
"Build Active Architecture Only" 设置为 "YES"
"Debug Information Format" 设置为 "DWARF with dSYM File"
"OS X Deployment Target" 设置为 "Compiler Default” 直接删除掉
"Skip Install" 设置为 "YES"
"Strip Debug Symbols During Copy" 中"Release"模式设置为 "YES"
"IOS Deployment Target" 设置为 "IOS 7.0"
"COMBINE_HIDPI_IMAGES" 设置为 "NO"

为什么要将Skip Install设置为YES?

Set the setting Skip Install to Yes for any static library or bundle target that you create. Check all the targets that are dependencies of your application project. If the option is No then you will be unable to build an archive of the project containing the target dependencies. Xcode will create a Generic Xcode Archive, which cannot be shared adhoc, validated, or submitted.

2.一般来说在制作静态库的时候,需要一个单独的bundle,framework本身已经包含了资源的结构.

2.使用bundle中的资源

 //bundle中加载Nib,需要重写init,基本上和继承基于nib的vc是一个写法.
 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    //FDResidentSelectVC 是基于nib的VC
    self = [super initWithNibName:@"FDResidentSelectVC" bundle:[BundleTools getBundle]];
    return self;
}

// get the resource bundle
NSString *resourceBundlePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"DTPinLockController" ofType:@"bundle"];
NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];

// load View Controller from that
UIViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:resourceBundle];

// load image from resource bundle
UIImage *image = [UIImage imageNamed:@"DTPinLockController.bundle/Image.png"];

// get a string
NSString *string = NSLocalizedStringFromTableInBundle(@"Set Passcode", @"DTPinLockController", resourceBundle, @"PinLock");
一

关于pod spec文件中的preserve_paths

一般来说,除了在podspec中指定的source,resource等会添加到工程,其它的一律删除. 那么有时候,想保留一些其它的额外的文件,那么这些子文件,就可以在preserve path中指定 'Clean' means that it will delete the files that should be 'cleaned' For example if you have a directory with a few files

  • source.h
  • source.m
  • readme.md
  • other.txt

If you just specify the source files as *.{h,m} then those will be added to the project and readme.md and other.txt will be removed. If you for some reason wanted the user to be able to access one of those files you would add it to the preserve_paths so it would not get delete. ref: stackoverflow.com/questions/1…

再比如下面在subspec中无法指定public_headers,就需要用preserve_paths来指定,并且还要在配置中指定一下header的查找位置: I managed to add the static library as a subspec. I prefer this approach because it uses the build shipped with my pod by default, and also enables users to provide their own build if they so desire. As mentioned, the static library is OpenSSL but the following applies to any static library. I'm using the following directory structure:

libraries/openssl-1.0.1e/include/openssl/*.h
libraries/openssl-1.0.1e/LICENSE
libraries/openssl-1.0.1e/lib/*.a

The resulting subspec would be:

s.subspec 'OpenSSL' do |openssl|
    openssl.preserve_paths = 'libraries/openssl-1.0.1e/include/openssl/*.h', 'libraries/openssl-1.0.1e/include/LICENSE'
    openssl.vendored_libraries = 'libraries/openssl-1.0.1e/lib/libcrypto.a', 'libraries/openssl-1.0.1e/lib/libssl.a'
    openssl.libraries = 'ssl', 'crypto'
    openssl.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/libraries/openssl-1.0.1e/include/**" }
end

Line by line:

openssl.preserve_paths = 'libraries/openssl-1.0.1e/include/openssl/*.h', 'libraries/openssl-1.0.1e/include/LICENSE'

Preserve headers and the license file. We will use the headers below.

openssl.vendored_libraries = 'libraries/openssl-1.0.1e/lib/libcrypto.a', 'libraries/openssl-1.0.1e/lib/libssl.a'

Tell CocoaPods that we are shipping the above static libraries in the pod. This will preserve the files, as well as modifying LIBRARY_SEARCH_PATHS accordingly.

openssl.libraries = 'ssl', 'crypto'

Includes the libraries in "Other Linker Flags".

openssl.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/#{s.name}/libraries/openssl-1.0.1e/include/**" }

Tells the project where to find the headers. We cannot use public_header_files because this is a subspec.

关于cocoa pods私有库

cocoapods应用第二部分-私有库相关 - yohunl的专栏 - 博客频道 - CSDN.NET

关于SDK编写经验:

2.制定好对于资源的管理策略,要分清NSBundle.

3.尽量不用precompiled header

4.尽量不要在header文件中直接import,除非必要,否则,直接用@class声明一下就行了.

5.如果使用了prefix header 那么需要在cocoapods中的 spec.prefix_header_file = 'iphone/include/prefix.pch' 指定一下.

关于Cocoapods项目原理1: 依赖关系

1.Cocoapods的主工程有一个dummy target,这个dummy target的作用就是让项目中其它的target可以编译:

1D0F4FD7-9BA7-45D6-8D25-49E5E7B05C0A.png

2.用户工程是通过设置查找引用路径,这个引用路径,就是上一步生成所需target的路径,来引用pod中所需要的target的.

205B3F77-EB87-447A-BC91-21A79ED73FB4.png

链接命令:

C4FAB71B-B402-4456-AC8F-70AE48AD6689.png

关于Cocoapods项目原理2: 工程配置

1.关于主工程中pod的相关编译配置,是通过xconfig文件来完成的:

6DAE8253-01BB-4F39-BB17-4E9A99378534.png

关于如何创建一个基于Pod spec 管理的工程

参考pod spec: Podspec文件

1.创建模板工程 pod lib create podTestLibrary

F18E1691-AB1C-4DA9-AE88-01A733C6C219.png

特别注意: 在编写podspec文件时,由于没有通过创建私有pod:
建立一个本地的私有repos
官方参考的私有
http://guides.cocoapods.org/making/private-cocoapods.html  Private Pods  写的很详细,并且还给出了示例
$ pod repo add REPO_NAME SOURCE_URL
其中的 REPO_NAME是我们要添加的私有repo的名称,后面的是其地址,注意这个只是创建而已,也就是只是在~/.cocoapods/repos 目录下 目录下添加了一个文件夹而已,但是,并没有在其中添加 spec文件

导致你在podspec文件当中书写形如,下面的方式,在pod的时候,会报错:
s.dependency 'AJKFrame'

一个解决方法是,在主工程中,书写:
pod 'AJKFrame', :path => '../../MVVM/AJKFrame'


对于依赖的系统库, 不必写前面的lib,以及后面的扩展名,比如后面的一项libc++.tbd,可以简写为c++
  s.library = "c++", "z", "stdc++.6.0.9", "sqlite3","iconv"

2.添加类文件,运行Example工程,测试正常以后,提交到git

$ git add .
$ git commit -s -m "Initial Commit of Library"
$ git remote add origin git@coding.net:wtlucky/podTestLibrary.git           #添加远端仓库
$ git push origin master     #提交到远端仓库
因为podspec文件中获取Git版本控制的项目还需要tag号,所以我们要打上一个tag,
$ git tag -m "first release" 0.1.0
$ git push --tags     #推送tag到远端仓库

3.运行pod lib lint 排查一下错误

依赖错误 但是,有些非语法错误是不会给出错误原因的。这个时候可以使用“--verbose”来查看详细的验证过程来帮助定位错误。

pod spec lint LPPushService.podspec --verbose 如下错误通过 --verbose 就可以找到原因。

 -> LPPushService (1.0.0)
    - ERROR | [iOS] Encountered an unknown error (The 'Pods' target has transitive dependencies that include static binaries: (/private/var/folders/jz/b_m3k7ln47524cm__h3__mk00000gn/T/CocoaPods/Lint/Pods/BPushSDK/LibBPush/libBPush.a)) during validation.

这个错误是因为依赖库(s.dependency)包含了.a静态库造成的。虽然这并不影响Pod的使用,但是验证是无法通过的。可以通过 --use-libraries 来让验证通过。

pod spec lint LPPushService.podspec --verbose --use-libraries 这种情况下使用 --use-libraries 虽然不会出现错误(error),但是有时候会带来一些警告(waring),警告同样是无法通过验证的。这时可以用 --allow-warnings 来允许警告。 pod spec lint LPPushService.podspec --verbose --use-libraries --allow-warnings

4.如果已经有了现成的项目,那么就需要给这个项目创建一个podspec文件,创建它需要执行Cocoapods的另外一个命令,官方文档在这里

$ pod spec create PodTestLibrary git@coding.net:wtlucky/podTestLibrary.git

5.提交到cocoapods官方:

注册trunk:

  pod trunk register  namel@gmail.com ‘your name' --description='macbook pro' --verbose
  pod trunk me 查看注册信息

在你podspec文件下的路径运行: pod trunk push

运行pod setup来更新你的Pods依赖库tree后,再使用pod search YXYNumberAnimationLabel命令来查找刚刚加入的名字叫YXYNumberAnimationLabel的依赖库

如果找不到的话,到这个目录下~/Library/Caches/CocoaPods/,将下面文件给删除掉,重新pod search就能找到了:

DAE3B9BD-EBB1-42DE-A035-DD28D3AFD9C0.png

ref: Cocoapods系列:制作自己的pods(二)

关于pod spec文件中资源的处理1.

一般资源可以通过如下:

s.resources='HealthMonitor/Assets/**/*.png','HealthMonitor/Assets/**/*.jpg','HealthMonitor/Classes/**/*.xib', 'HealthMonitor/Classes/**/*.storyboard'
    来包含所需要的资源,但是有一点得注意,在pod spec项目中引用这引起资源时要改变写法,就是得要用[NSBundle bundleForClass:[self class]] 来显式的指明一下bundle.

1.引用图片:
        self.iconImageView.image =   [UIImage imageNamed:@"list_rengong" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
 
2.引用storyboard文件:
     NSBundle* bundle=[NSBundle bundleForClass:[self class]];
        BloodPressureViewController *controller = [[UIStoryboard storyboardWithName:@"HealthMonitor" bundle:bundle]  instantiateViewControllerWithIdentifier:@"BloodPressureViewController"];

3.引用xib文件:
        BodyFatRatioDetailViewController *BloodVC = [[BodyFatRatioDetailViewController alloc]initWithNibName:@"BodyFatRatioDetailViewController" bundle:[NSBundle bundleForClass:[self class]]];

ref:iOS中Framework中使用记录 - LeiYinchun's blog

关于pod spec文件中资源的统一放入bundle中进行管理

在pod spec文件中添加如下:

s.resource_bundles = {
'HealthMonitorLib' => ['HealthMonitor/Assets/**/*.png',
                    'HealthMonitor/Assets/**/*.jpg',
                    'HealthMonitor/Classes/**/*.xib',
                    'HealthMonitor/Classes/**/*.storyboard'
                   ]
}

那么在User Target生成的app包中就会包含HealthMonitorLib.bundle. 那么访问其中的资源:

NSBundle* bundle=[NSBundle bundleForClass:[self class]];
NSString*   resourcePath=[ pathForResource:@"HealthMonitorLib" ofType:@"bundle”];
NSBundle* resourceBundle=[NSBundle bundleWithPath:bundle];
self.iconImageView.image =   [UIImage imageNamed:@"list_shebeiluru" inBundle:resourceBundle  compatibleWithTraitCollection:nil];

ref:给 Pod 添加资源文件

关于pod spec文件的写法

1.关于pod spec文件的解释

s.name:名称,pod search 搜索的关键词
s.version:版本
s.summary:简介,pod search 搜索的关键词
s.homepage:主页地址,例如Github地址
s.license:许可证
s.author:作者
s.social_media_url:社交网址
s.platform:平台
s.source:Git仓库地址,例如在Github地址后边加上 .git 就是Git仓库地址,常见写法如下
s.source_files:需要包含的源文件,常见的写法如下
s.resources:需要包含的图片等资源文件
s.dependency:依赖库,不能依赖未发布的库
s.dependency:依赖库,如有多个可以这样写
s.requires_arc:是否要求ARC

2.s.source_files 常见写法

"Directory1/*"
"Directory1/Directory2/*.{h,m}"
"Directory1/**/*.h"
**” 表示匹配所有文件
**.{h,m}” 表示匹配所有以.h和.m结尾的文件
* “**” 表示匹配所有子目录

关于pod spec使用中出现include of non-modular header inside framework module错误的处理 1.pod spec文件编写好之后,集成到项目中出现如下错误: include of non-modular header inside framework module 那么解决办法是是pod spec文件中添加如下配置文件:

s.pod_target_xcconfig = { 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES'
}

找到上面配置的步骤是:

1.找到这个配置

46D2E082-297A-46B6-99A7-7A160FC48181.png 2.选中它,然后拷贝. 再到别的文本文件中粘贴,即可得到这个配置对应的编译选项

podfile 模板

platform :ios, '9.0'
inhibit_all_warnings!

target 'MyApp' do
  pod 'ObjectiveSugar', '~> 0.5'

  target "MyAppTests" do
    inherit! :search_paths
    pod 'OCMock', '~> 2.0.1'
  end
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    puts "#{target.name}"
  end
end

######################################################################################

platform :ios,'7.0'
workspace 'W.xcworkspace'
abstract_target ‘W’ do
    #pod 'ObjectiveSugar', '~> 0.5' #下面的target会继承这一个依赖
    target ‘Maindo
        project ‘Main/Main’
        pod 'TMCache','2.1.0'
        pod 'ReactiveCocoa', '2.4.7'
    end

    target ‘Libdo
        project ‘Lib/Lib’
        inherit! :search_paths      #仅继承头文件搜索路径
    end
end

######################################################################################

platform :ios,'7.0'
workspace 'W.xcworkspace'
abstract_target ‘W’ do
    #下面两个是Lib中使用的依赖
    pod 'TMCache','2.1.0'
    pod 'ReactiveCocoa', '2.4.7'
    target ‘Maindo
        #这个是Main中特有的依赖
        pod 'MBProgressHUD','0.9.1' 
        project ‘Main/Mainend

    target ‘Libdo
        project ‘Lib/Lib’
        inherit! :search_paths
    end
end

######################################################################################

pod install 和 pod update的区别

1.当项目第一次使用pod来初始化的时候,应该使用pod install,这时会生成一个Podfile.lock文件. 这个文件记录着该项目所使用的依赖的精确版本号. 那么当另外一个用户使用同样的podfile来初始化工程的时候,cocoapods就可以根据Podfile.lock中的记录,来安装同样版本的依赖. 从而保证了开发的一致性. 也就是说pod install 对于已经存在的依赖,始终是以Podfile.lock中的记录为准

2.当我们从podfile中添加,删除依赖的时候,应该使用pod install

3.从上面的作用,我们可以看到,Podfile.lock也是应该提交到svn当中的.

4.当我们需要更新Podfile.lock或Podfile中依赖的版本的时候,这时可以使用 pod update [依赖名称] 来更新特定的依赖,或者是不加参数来更新所有的依赖,这时Podfile.lock也会相应的被更新.

5.可以使用pod outdated 来查看当前Podfile.lock中哪些依赖是过时的,也就是说这些依赖有了新的版本.

6.通过在podfile指定特定版本的方式,是不能实现Podfile.lock的效果的. 比如pod 'A', ‘1.0.0’. 有可能是A中的依赖如下: A.podspec as dependency 'A2', '~> 3.0’ 那么在不同的时间运行pod install,就可能安装不同的依赖.

ref:app.yinxiang.com/shard/s7/nl…

关于pod search

pod list和pod search命令只搜索存在于本地~/.cocoapods文件夹的所有第三方库,并不会连接到远程服务器。如果你要从服务器更新本地第三方库的描述文件,可以:

$ pod repo update master

pod setup用于初始化本地第三方库的Spec描述文件,所有的spec文件存都存放在~/.cocoapods目录中。

关于cocoapods的常用命令 cocoapods的常用命令

pod list  列出所有可用的第三方库
pod search query 搜包含query的第三方库   注意:这两个命令只搜存在于本地 /Users/yohunl/.cocoapods/ 下的文件
如果搜索网络的,可以先更新本地  pod repo update master,然后再搜索
pod lib create frameworkName  创建一个framework工程

pod spec lint —用来验证本地使用pod spec create添加的podspec文件(但是,这个命令常常会出现 2 out of 2 specs failed validation.此类的错误,故推荐大家都使用 pod lib lint)
pod lib lint  这个是检验由pod lib create创建的lib工程的spec的合法性(经过检验,这个命令是也是可以适用于第一种情况的.)


podinstall --no-repo-update错误 这里的参数—no-repo-update,是告诉cocoapods不要更新repo.有么有感觉每次pod install都很慢,那是因为每一次都会先更新本地的repo,加上此参数,就跳过了这个过程,将会很快
pod init 可以建立一个空的podfile
建立pod的spec文件   pod spec create spec名字  http://www.theonlylars.com/blog/2013/01/20/cocoapods-creating-a-pod-spec/
pod install 命令时会引发许多操作。要想深入了解这个命令执行的详细内容,可以在这个命令后面加上 --verbose
我们删除我们添加的私有库 [哈哈,其实你都显示了隐藏目录了,也可以直接进去直接删除文件夹的!]
pod repo remove yohunl
pod repo remove yohunlSpecs

在终端执行命令  pod repo add yohunlSpecs  git@github.com:yohunl/yohunlSpecs.git  或者  pod repo add yohunlSpecs  https://github.com/yohunl/yohunlSpecs.git  ,很多文章说,这里最好是采用http模式的git地址,不过我试了,两者都是可以的,执行命令后
在.cocoapods目录下

53BFF429-D13B-4236-BF0D-87CF5CD6364F.png

看到没,这里出现了一个我们自己的私有仓库 yohunlSpecs,这是一个空的仓库

ref: cocoapods应用第二部分-私有库相关 - yohunl的专栏 - 博客频道 - CSDN.NET

解决pod search出来的仓库版本低于github仓库版本的方法

问题描述 我们在用 Cocoapods 做第三方开源库管理的时候,有时候发现

$ pod search XXX

版本低于github上仓库的最新release版本 (注:XXX为仓库名称)

解决方法-->升级Cocoapods版本 查看当前系统Cocoapods版本命令:pod --version

升级方法 卸载cocopods: 执行命令 sudo gem uninstall cocoapods -v 版本号

$ sudo gem update --system
$ gem sources --remove https://rubygems.org/ 
$ gem sources -a https://ruby.taobao.org/ 
$ sudo gem install cocoa pods 
 #如果出错则用sudo gem install -n /usr/local/bin cocoapods
$ pod setup

其中

$ gem sources --remove https://rubygems.org/ 
$ gem sources -a https://ruby.taobao.org/ 

这两句话可以省略,但我们在天朝,还是加上的好。国内网络原因(你懂的),如果使用原来的rubygems.org/,那么在sudo gem install cocoapods的时候,存放在 Amazon S3 上面的资源文件间歇性连接失败。 升级结束后再次pod --version,会发现 Cocoapods 版本号高于之前的版本,升级成功了。 再次

$ pod search XXX

OK,github仓库的最新版已经有了。

问题经过:[HeshamMegid/HMSegmentedControl#77)(github.com/HeshamMegid…)

遇到下面问题的解决方案是:在工程中找到OTHER_LDFLAGS,然后按回车,直到这个选项黑色高亮消失. 然后重新Pod update一下.

[!] The `Lib [Debug]` target overrides the `OTHER_LDFLAGS` build setting defined in `../Pods/Target Support Files/Pods-Lib/Pods-Lib.debug.xcconfig'. This can lead to problems with the CocoaPods installation
    - Use the `$(inherited)` flag, or
    - Remove the build settings from the target.
[!] The `Lib [Release]` target overrides the `OTHER_LDFLAGS` build setting defined in `../Pods/Target Support Files/Pods-Lib/Pods-Lib.release.xcconfig'. This can lead to problems with the CocoaPods installation

遇到下面问题的解决方案是:pod search not work JSON ParserError

删除 ~/Library/Caches/CocoaPods/search_index.json,重新search即可

通过子工程来管理不同的库

1.创建文件夹,首先新建一个.xcworkspace文件. 然后在该文件夹直接建立主工程.xcodeproj文件,库工程的.xcodeproj文件. 库工程要建立framework的方式. 2.将主工程的.xcodeproj,库工程的.xcodeproj文件分别拖入到.xcworkspace中. 并设置主工程引用库工程.

2B6A7C64-F96E-4489-B165-46D694083890.png

2.1 Lib framework的导出header设置要注意:

FE4FFA88-6C89-47D6-B4A9-3094E641A552.png

3.然后在.xcworkspace文件所在的目录中,创建Podfile. 注意由于库工程,都会在主工程中被引用. 所以同一个第三方只能出现一次

platform :ios,'7.0'
workspace 'U.xcworkspace'
target ‘Maindo
pod 'TMCache','2.1.0'
project ‘Main/Mainend

target ‘Libdo
pod 'ReactiveCocoa', '2.4.7'
project ‘Lib/Libend

777A8B9A-299A-4114-A40F-1900C030D651.png

4.通常情况一下,在mac中一个程序只能打开其中的一个实例,通过这个命令 open -n -a "APPLICATION NAME” 可以打开应用程序新的实例 www.cnet.com/news/how-to…

Update: When running pod install --verbose Integrating client project Integrating target Pods (AIYOCore.xcodeproj project) [!] The use of implicit sources has been deprecated. To continue using all of the sources currently on your machine, add the following to the top of your Podfile: source 'github.com/CocoaPods/S…' [!] The Project [Debug] target overrides the OTHER_LDFLAGS build setting defined in `Pods/Target Support Files/Pods/Pods.debug.xcconfig'. This can lead to problems with the CocoaPods installation

  • Use the $(inherited) flag, or
  • Remove the build settings from the target.

[!] The Project [Release] target overrides the OTHER_LDFLAGS build setting defined in `Pods/Target Support Files/Pods/Pods.release.xcconfig'. This can lead to problems with the CocoaPods installation

  • Use the $(inherited) flag, or
  • Remove the build settings from the target. It seems like you don't have $(inherited) in OTHER LINKER FLAGS. Please post output of the pod install

stackoverflow.com/questions/2…

There is a conflict between your build settings and the default build settings that Cocoapods wants. To see the Cocoapods build settings, view the file at Pods/Pods.xcconfig in your project. For me this file contains:

GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/Commando"
OTHER_LDFLAGS = -ObjC -framework Foundation -framework QuartzCore -framework UIKit
PODS_ROOT = ${SRCROOT}/Pods

If you are happy with the Cocoapods settings, then go to Build Settings for your project, find the appropriate setting and hit the Delete key. This will use the setting from Cocoapods. On the other hand, if you have a custom setting that you need to use, then add $(inherited) to that setting.

stackoverflow.com/questions/1…

2.xccheckout是否可以忽略,在svn中?

如果是只是单个工程的话,在单一一个repository的话,是可以忽略的. 如果你的项目是一个workspace里面包含多个来自不同repository的话,那么,就不可以省略 You should check in an Xcode 5 .xccheckout file; in general, files in xcshareddata should be committed.

An .xccheckout file contains metadata about what repositories are used in a workspace. For a single project in a single repository that doesn't make much difference. But if you're using a workspace that has multiple projects from different repositories, the presence of an .xccheckout file in the workspace allows Xcode to know what all of the components that make up a workspace are and where to get them. stackoverflow.com/questions/1…

1.svn设置忽略属性:

svn propset svn:ignore xcuserdata path/to/my/folder/MyProject.xcodeproj 或修改配置文件: global-ignores = *.o *.lo .la ..rej .rej .~ ~ .# .DS_Store *~.nib .mode .pbxuser CVS _.java *.perspective .LSOverride *.xcuserdatad blog.csdn.net/houseq/arti…