XCTest简介

准备工作

对于新项目,在新建项目界面勾选上UI Tests;

对于旧项目,在项目界面点击菜单栏中的File→New→Target…→iOS→Test→iOS UITesting Bundle。

sleepForTimeInterval:

线程休眠

[NSTread sleepForTimeInterval:1.0f];

也可以使用sleep(3),OC兼容C语言。

定义测试用例

XCTestCase

+ (void)setUp;
在类中的第一个测试方法调用之前调用,区别于-(void)setUp:在每个测试方法调用之前都调用。

+ (void)tearDown;
在类中的最后一个测试方法完成后调用。区别于-(void) tearDown:在每个测试方法调用后都调用。

异步测试表达式

*-(XCTestExpectation *)expectationWithDescription:(NSString )description;
指定时间内满足测试条件则测试通过,超时则输出description。

- (void)testAsynExample {
XCTestExpectation *exp =[self expectationWithDescription:@"这里可以是操作出错的原因描述。。。"];
NSOperationQueue *queue =[[NSOperationQueue alloc]init];

[queue addOperationWithBlock:^{
//模拟这个异步操作需要2秒后才能获取结果,比如一个异步网络请求
sleep(2);
//模拟获取的异步操作后,获取结果,判断异步方法的结果是否正确
XCTAssertEqual(@"a",@"a");
//如果断言没问题,就调用fulfill宣布测试满足
[exp fulfill];

}];

//设置延迟多少秒后,如果没有满足测试条件就报错

[self waitForExpectationsWithTimeout:3 handler:^(NSError * _Nullable error){

if(error){
NSLog(
    @"Timeout Error: %@", error);
}
}];

}

*-(XCTestExpectation *)expectationForPredicate:(NSPredicate )predicate evaluatedWithObject:(id)object handler:(XCPredicateExpectationHandler)handler;

利用谓词计算,如果限定时间内满足条件则通过测试

- (void)testThatBackgroundImageChanges {

    XCTAssertNil([self.button backgroundImageForState:UIControlStateNormal]);

    NSPredicate *predicate =[NSPredicate predicateWithBlock:^BOOL(UIButton * _Nonnull button,NSDictionary<NSString *,id>* _Nullable bindings){

    return[button backgroundImageForState:UIControlStateNormal]!=nil; 
    }];

[self expectationForPredicate:predicate evaluatedWithObject:self.button handler:nil];
[self waitForExpectationsWithTimeout:20 handler:nil];
}

*-(XCTestExpectation *)expectationForNotification:(NSString )notificationName object:(id)objectToObserve handler:(XCNotificationExpectationHandler)handler;

监听一个通知,如果在规定时间内正确收到通知则测试通过。

- (void)testAsynExample1 {
    [self expectationForNotification:(@"监听通知的名称xxx") object:nil handler:nil];
    [[NSNotificationCenter defaultCenter]postNotificationName:@"监听通知的名称xxx" object:nil];
    //设置延迟多少秒后,如果没有满足测试条件就报错
    [self waitForExpectationsWithTimeout:3 handler:nil];
}

*- (XCTestExpectation *)keyValueObservingExpectationForObject:(id)objectToObserve keyPath:(NSString )keyPath expectedValue:(id)expectedValue;

创建一个KVO观察模式

- (XCTestExpectation *)keyValueObservingExpectationForObject:(id)objectToObserve keyPath:(NSString *)keyPath handler:(XCKeyValueObservingExpectationHandler)handler;

创建一个KVO观察模式

-(void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout handler:(XCWaitCompletionHandler)handler;

设定等待时间,等待时间内满足所有条件则测试通过,成功或超时都会执行handler block(optional)

typedef BOOL (^XCPredicateExpectationHandler)(void);

如果未提供Handle,第一次测试通过即满足条件,如果提供了Handle,它能覆盖原有的行为和条件,那么将重新判定是否满足条件。

typedef BOOL(^XCNotificationExpectationHandler)(NSNotification *notification);

获得符合期望的通知时将被调用,满足条件为Yes

typedef BOOL (^XCKeyValueObservingExpectationHandler)(id observedObject, NSDictionary *change);

当KVO监视的值反正改变是调用,满足条件为Yes

typedef void(^XCWaitCompletionHandler)(NSError *error);

当测试成功或超时时调用,需要指定error类型,否则error = nil;

@property BOOL continueAfterFailure;
默认为Yes,当case中某条测试语句失败时会继续向下执行,实测只向下执行了一步,待验证。

- (void)measureBlock:(void(^)(void))block;

测试块中代码的性能。

  • (void)measureMetrics:(NSArray*)metrics automaticallyStartMeasuring:(BOOL)automaticallyStartMeasuring forBlock:(void()(void))block;

measureBlock的拓展版,当需要自定义测量的开始点和结束点时,又或者要测量多个指标时调用此方法。

Metrics:是测量标准数组;automaticallyStartMeasuring为真时,自动开始测试,为假则需要startMeasuring作为启动点。

注意在一个代码块中开始点和结束点只能各有一个,出现一下情况时测试将会失败: automaticallyStartMeasuring = YES且代码块中调用了startMeasuring方法; automaticalltStattMeasuring = NO 且代码块中没调用或多次调用了startMeasuring方法;

在代码块中多次调用了stopMeasuring方法。

-(void)startMeasuring;

在measureBlock中调用此方法来标记一个测量起点。

-(void)stopMeasuring;

在measureBlock中调用此方法来标记一个结束点。

+(NSArray*)defaultPerformanceMetrics;

这是调用measureBlock时默认使用的测量标准数组。

-(id)addUIInterruptionMonitorWithDescription:(NSString *)handlerDescription handler:(BOOL()(XCUIElement

*interruptingElement))handler;

在当前上下文中添加一个Handle

handlerDescription:用于阐述这个Handle的作用和行为,主要被用来Debug和分析异步测试

XCTestExpectation

使用以下XCTestCase方法来创建XCTestExpectation实例: expectationWithDescription:

expectationForPredicate:evaluatedWithObject:handler: expectationForNotification:object:handler: keyValueObservingExpectationForObject:keyPath:expectedValue: keyValueObservingExpectationForObject:keyPath:handler:

-(void)fulfill;

为满足条件的表达式做标记

布尔值检测

XCTAssert / XCTAssertTrue

断言表达式为真,XCTAssert(expression, format...)当expression求值为TRUE时通过; XCTAssert([image exists]);

XCTAssertTrue(expression, format...)当expression求值为TRUE时通过; XCTAssertTure([image exists]);

XCTAssertFalse

表达式为假,XCTAssertFalse(expression, format...)当expression求值为False时通过; XCTAssertFalse(![image exists]);

空值检测

XCTAssertNil

表达式的值为空,XCTAssertNil(a1, format...)为空判断,a1为空时通过,反之不通过; NSArray *array =nil;

XCTAssertNil(array);

XCTAssertNotNil

表达式的值非空,XCTAssertNotNil(a1, format…)不为空判断,a1不为空时通过,反之不通过; NSArray *array =[NSArray array];

XCTAssertNotNil(array);

等式检测

XCTAssertEqual

XCTAssertEqual(a1, a2, format...)判断相等(当a1和a2是C语言标量、结构体或联合体时使用, 判断的是变量的地址,如果地址相同则返回TRUE,否则返回NO);

XCTAssertEqual(array,array2,@"失败时输出");

XCTAssertEqualObjects

XCTAssertEqualObjects(a1, a2, format...)判断相等,[a1 isEqual:a2]值为TRUE时通过,其中一个不为空时,不通过;

XCTAssertEqualObjects(array,array2,@"失败时输出"); XCTAssertEqualWithAccuracy

XCTAssertEqualWithAccuracy(a1, a2, accuracy, format...)判断相等,(double或float类型)提供一个误差范围,当在误差范围(+/-accuracy)以内相等时通过测试; XCTAssertEquallWithAccuracy(array,array2,@"失败时输出");

不等式检测

XCTAssertNotEqual

XCTAssertNotEqual(a1, a2, format...)判断不等(当a1和a2是C语言标量、结构体或联合体时使用);

XCTAssertNotEqual(array,array2,@"失败时输出"); XCTAssertNotEqualObjects

XCTAssertNotEqualObjects(a1, a2, format...)判断不等,[a1 isEqual:a2]值为False时通过; XCTAssertNotEqualObjects(array,array2,@"失败时输出"); XCTAssertNotEqualWithAccuracy

XCTAssertNotEqualWithAccuracy(a1, a2, accuracy, format...) 判断不等,(double或float类型)提供一个误差范围,当在误差范围以内不等时通过测试; XCTAssertNotEquallWithAccuracy(array,array2,@"失败时输出");

相对值检测

XCTAssertGreaterThan:A > B

XCTAssertGreaterThan(floatB,floatA,@"Fail Output"); XCTAssertGreaterThanOrEqual:A ≥ B

XCTAssertGreaterThanOrEqual(floatB,floatA,@"Fail Output"); XCTAssertLessThan:A< B

XCTAssertLessThan(floatB,floatA,@"Fail Output"); XCTAssertLessThanOrEqual:A ≤ B

XCTAssertLessThanOrEqual(floatB,floatA,@"Fail Output");

异常检测

XCTAssertThrows(expression, format...)

异常测试,当expression发生异常时通过;反之不通过;

XCTAssertThrowsSpecific(expression, specificException, format...)

异常测试,当expression发生specificException异常时通过;反之发生其他异常或不发生异常均不通过;

XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...)

异常测试,当expression发生具体异常、具体异常名称的异常时通过测试,反之不通过; XCTAssertNoThrow(expression, format…)

异常测试,当expression没有发生异常时通过测试;

XCTAssertNoThrowSpecific(expression, specificException, format...)

异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过; XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...) 异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过。无条件失败断言

XCTFail

无条件产生一个失败的结果。

XCTFail();

UI Testing

XCUIElements API

exists

判断控件对象是否存在。BOOL类型。

[textField exists]

debugDescription

保存某控件的debug信息,这些信息只能用于调试case,NSString类型。

NSLog(@"%@",[textField debugDescription]);

hittable

BOOL类型的只读属性,表示当前元素能否获取到坐标。

descendantsMatchingType

从该控件下所有子控件中找到符合指定类型的控件,需要传入XCUIElementType(枚举类,定义了iOS中所有可定位的控件)类型的参数,返回包含了XCUIElementType类型的XCUIElementQuery数组。

XCUIElementQuery *textFields =[cell

childrenMatchingType:XCUIElementTypeTextField];

childrenMatchingType

只从与该控件有直接关系的子控件中找到符合指定类型的控件,需要传入XCUIElementType 类型的参数,返回包含了XCUIElementType类型的XCUIElementQuery数组。XCUIElementQuery *textFields =[cell

descendantsMatchingType:XCUIElementTypeTextField];

tap

单击

[app.tables.staticTexts[@"Groceries"]tap];

。doubleTap

双击

[buttondoubletap];

twoFingerTap

双指单击

[app twoFingerTap];

pressForDuration(duration: NSTimeInterval)

长按,时间由传入的参数定义,单位为秒

[textField pressForDuration:5.5];

pressForDuration(duration: NSTimeInterval, thenDragToElement otherElement: XCUIElement) 长按拖拽。在控件上长按后,拖拽到另外一个控件。传入2个参数:长按时间和拖拽到目标控件。

[textField pressForDuration:5.5, thenDragToElement:table];

swipeUp/ swipeDown/ swipeLeft/ swipeRight

从下划到上/从上滑到下/从右滑到左/从左滑到右

[app swipeUp];

typeText

输入字符。需要一个参数:NSString

[addItemTextField typeText:@"Hello"];

tapWithNumberOfTaps:numberOfTouches:

多触摸点及多次点击

[windows tapWithNumberOfTaps:3 numberOfTouches:2];

pinchWithScale:velocity:

捏合手势scale=0~1为捏合、>1为放大,velocity为捏合速度

[windows pinchWithScale:0.2 velocity:-0.05];

当01时,velocity必须大于0,time(s) = scale/velocity。

[img pinchWithScale:0.5 velocity:0.2];

rotate:withVelocity:

旋转手势rotate:要旋转的弧度withVelocity:每秒要旋转的弧度

Rotate和Velocity必须同号顺时针为正向。

[img rotate:2 withVelocity:0.4];

normalizedSliderPosition

只读属性,返回滑块控件中滑块的位置(0~1) adjustToNormalizedSliderPosition:

尽可能让滑块移动到指定的位置(0-1)

adjustToPickerWheelValue:

输入字符串让选择器显示对应内容,如果没有对应内容,返回Fail coordinateWithNormalizedOffset:

根据控件的原点坐标和偏移量来确定一个新坐标

[element coordinateWithNormalizedOffset:CGVectorMake(10,10)]; XCUIApplication API

XCTest新加的类,用于做UI测试,代表被测应用,父类为XCUIElement

launch

启动应用。如果目标应用已运行,首先终止应用,然后再次启动应用。[applaunch];

terminate

关闭应用。

[app terminate];

launchArguments

数组对象,保存启动参数。

NSArray*args=[applaunchArguments];

for(int i=0;i<[argscount];i++){

NSLog(@"arg : %@",[argsobjectAtIndex:i]);

}

launchEnvironment

字典对象,保存启动环境变量

NSDictionary *env =[app launchEnvironment];

for(id key in env){

NSString *object=[env objectForKey:key];

NSLog(@"env : %@",object);

}

XCUIElementAttributesAPI

协议类,XCUIElement遵守的协议

identifier

字符串类型Accessibility ID

NSString *identifier =[app identifier];

.frame

控件的矩形区域

CGRect frame =[app frame];

Value

获取元素的原值

id value =[app value];

placeholderValue

返回元素的占位值

title

标题,String类型

NSString *title =[app title];

label

标签值,String类型

NSString *label =[app label];

elementType

控件类型

XCUIElementType *elementType =[app elementType];

enabled

是否可用,BOOL类型

BOOL*isEnabled =[app isEnabled];

hasFocus

是否具有UI焦点

Selected

是否处于被选中状态

horizontalSizeClass

返回水平尺寸元素

XCUIUserInterfaceSizeClass *horizontalSizeClass =[app horizontalSizeClass];

verticalSizeClass

返回垂直尺寸元素

XCUIUserInterfaceSizeClass *verticalSizeClass =[app verticalSizeClass];

XCUIElementQueryAPI

定位元素的对象,可以理解为存放控件的容器

element

query用element表示形式,如果query中只有一个元素,可以讲element当成真正的element,执行点击等操作,从这一方面来讲XCUIElementQuery其实也是一种XCUIElement对象,只是是用来存放0~N个XCUIElement的容器。得到XCUIElement对象。

count

query中找到的元素数量,得到整数。

allElementsBoundByAccessibilityElement

query中根据accessibility element得到的元素数组。得到XCUIElement数组

allElementsBoundByIndex

query中根据索引值得到的元素数组。得到XCUIElement数组

debugDescription

调试信息

  • 。:

获得传入的索引值所在的元素,返回XCUIElement对象。

elementMatchingPredicate

根据NSPredicate定义的匹配条件查找元素。返回XCUIElement对象。只能从当前对象中查找。更深层次的元素不在查找范围内

elementMatchingType

根据元素类型(XCUIElementType)和id号来匹配查找元素。返回XCUIElement对象。只能从当前对象中查找。更深层次的元素不在查找范围内

descendantsMatchingType

传入XCUIElementType作为匹配条件,得到匹配的XCUIElementQuery对象,查找对象为当前控件的子子孙孙控件。返回XCUIElementQuery对象

childrenMatchingType

传入XCUIElementType作为匹配条件,得到匹配的XCUIElementQuery对象,查找对象为当前控件的子控件。返回XCUIElementQuery对象

matchingPredicate

传入NSPredicate作为过滤器,得到XCUIElementQuery对象。返回XCUIElementQuery对象

matchingType

传入XCUIElementType和id号作为匹配条件,得到XCUIElementQuery。返回XCUIElementQuery对象

matchingIdentifier

传入id号作为匹配条件,得到XCUIElementQuery。返回XCUIElementQuery对象

containingPredicate

传入NSPredicate过滤器作为匹配条件。从子节点中找到包含该条件的XCUIElementQuery 对象

containingType

传入XCUIElementType和id作为匹配条件。从子节点中找到包含该条件的XCUIElementQuery对象。

XCUIElementTypeAPI & XCUIElementTypeQueryProvider API 枚举类,定义了iOS中所有的可用于搜索类型

XCUIElementTypeQueryProvider协议中定义了76个变量,与XCUIElementType定义的枚举元素相比少了3个:Any,Unknown,Application。因为XCUIApplication也遵循该协议,所以Application对象包含XCUIElementTypeQueryProvider定义的所有属性,所以要过滤掉以上三个大于Application的类型。

除了特殊注明的,XCUIElementQuery都是原来类型的复数形式

UIView的定位方式:app.otherElements[@”id”];

2018/9/13 posted in  Xcode

Xcode 插件主题-Dracula

Dracula for Xcode

A dark theme for Xcode.

Screenshot

Install

All instructions can be found at draculatheme.com/xcode.

Team

This theme is maintained by the following person(s) and a bunch of awesome contributors.

Harrison Heck
Harrison Heck

License

MIT License

2018/8/31 posted in  Xcode

关于Xcode “Build Setting”中的Architectures详解

基本概念

  • ARM架构,是一种低成本、高性能、低耗电处理器架构,目前广泛的在移动通信领域中使用。
  • ARM处理器指令集 苹果A7处理器支持两个不同的指令集:32位ARM指令集(armv6|armv7|armv7s)和64位ARM指令集(arm64)。 i386|x86_64 是Mac处理器的指令集,i386是针对intel通用微处理器32架构的。x86_64是针对x86架构的64位处理器。当使用iOS模拟器的时候会遇到i386|x86_64,iOS模拟器没有arm指令集。
  • 目前iOS移动设备指令集
    ARMv8/ARM64: iPhone 6(Plus), iPhone 5s, iPad Air(2), Retina iPad Mini(2,3)
    ARMv7s: iPhone 5, iPhone 5c, iPad 4
    ARMv7: iPhone 3GS, iPhone 4, iPhone 4S, iPod 3G/4G/5G, iPad, iPad 2, iPad 3, iPad Mini
    ARMv6: iPhone, iPhone 3G, iPod 1G/2G
    “Build Setting” 中Architecture详解

  • Architectures
    指定工程支持的指令集的集合,如果设置多个architecture,则生成的二进制数据包会包含多个指令集代码,体积会变大。

  • Valid Architectures
    有效的指令集集合,Architectures与Valid Architectures 的交集来确定最终的数据包包含的指令集代码。

  • Build Active Architecture Only
    指定是否只对当前连接设备所支持的指令集编译,默认Debug的时候设置为YES,Release的时候设置为NO。设置为YES是只编译当前的architecture版本,生成的包只包含当前连接设备的指令集代码。设置为NO,则生成的包包含所有的指令集代码(上面的Valid Architectures跟Architectures的交集)。因此为了调试速度更快,则Debug应该设置为YES。
    特殊:设置此值为YES,如果连接的设备是arm64的( iPhone 5s,iPhone6(plus)等),则Valid Architecture 中必须包含arm64, 否则编译会报错(报错的内容在下面常见问题中)。
    总结一下,按照新版Xcode6.1.1的默认设置就没有任何问题,之前的Xcode版本开发的项目也建议升级到Xcode6.1.1,同样按照如下配置:

  • Architectures 默认设置为 Standard architectures(armv7,arm64) 。(之前的Xcode版本中默认设置还包括armv7s,现在去掉了,估计是因为armv7s相较armv7优化不大,能向下兼容,而设置后还会增大二进制包的大小)

  • Valid Architectures 默认设置为 armv7 armv7s arm64。

  • Build Active Architecture Only:默认Debug的时候设置为YES,Release的时候设置为NO。

    App适配64位

  • 为什么要适配64位?
    1: 苹果官方要求: 2015年2月1日起,提交到AppStore的新应用必须支持64bit,6月1日起,更新的app也必须支持64bit。详见官方文档。
    2: 为了提升性能:目前A7使用的是ARM V8架构,除了使用64位的地址总线和64位的寄存器以外,还增加了寄存器的数量,目前A7中的整数和浮点数寄存器是A6的两倍。寄存器的增加提高了程序的运行速度。详见官方文档。再者,64位系统为了兼容32位的程序,64位的iOS系统中带有两套Framework,一套32位的,一套64位的。当64位的iOS系统运行原来的32位程序时,系统会调用32位的Framework作为底层支撑,当系统运行64位程序时,系统会调用64位的Framework作为底层支撑,所以如果app不做64位适配的话,系统会调用32位Framework,消耗内存增多,运行速度会变慢。

  • 如何适配64位?
    1:Xcode版本号>5.0.1。(建议升级到最新版本)
    2:minimum deployment target > 5.1.1。
    3:按照上述Xcode6的默认配置进行配置,其他Xcode版本最好也进行如此配置。
    4:运行测试代码,解决编译warnings and errors,对照本文档或者官方文档 64-Bit Transition Guide for Cocoa Touch对相应地方做出修改。(编译器不能告诉我们一切)
    5:在真实的64-bit机器上测试。
    6:使用Instruments查看内存使用问题。

此贴只进行简要介绍,具体详见iOS工程如何支持64-bit或者苹果官方文档

关于Architecture的常见问题

  1. 编译报错 No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).

问题起因:active architecture(当前连接设备的指令集)为64位指令集,但是valid architecture只包含32位指令集
解决方法:valid architecture增加arm64 (常见的一些帖子的解决方案是把Build Active Architecture Only设置为NO,这是个简单粗暴的解决办法,在Debug过程中也会生成包含所有指令集的代码,更何况现在官方强制必须支持64位,故不建议采纳)
2. No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=i386, VALID_ARCHS=x86_64).

问题起因:跟上个问题同理,只不过连接的设备指令集是32位指令集,但是valid architecture只包含64位指令集
解决办法:valid architecture增加armv7
3. App在打包submit到Appstore中,提示需要支持64bit,或者在App提交完成后Apple发Missing 64-bit support 内容的邮件给开发者。

解决办法: App按照上述适配64位的步骤进行适配。
4. 导入静态库后编译报错为

问题起因:1:可能是静态库中不包含这个类。
2:静态库工程可能没有链接到应用。
3:可能是因为静态库(.a)为真机版本,不包含模拟器版本(i386)。
解决办法:1:查看静态库里面是否存在这个类。
2:Build Phases中没有添加Link Binary With Libraries 中添加此静态库。
3:把调试目标换成真机 或者 导入一个模拟器版本跟真机版本合并的版本
同理如果导入的库是模拟器版本而用真机调试也会报错,所以导入一个通用的版本是目前来讲最好的办法。
5. 导入静态库后编译报错为

问题起因:1:可能原因同上,因为静态库不包含报错的类
2:可能原因同上,因为静态库程可能没有链接到应用。
3:可能是因静态库不支持64位
解决办法:排除前两个可能原因后,来看第三个起因的解决办法:查看静态库的提供方是否有更新支持64位,如果最新的静态库依然不支持64位的话,则需要获取其源码重新打包静态库,valid architecture中添加arm64。
详细的解决办法参考stackoverflow。如果不能获得源代码的话,鉴于目前苹果官方需要支持64位,所以只能换别的静态库了,否则联系开发者进行静态库更新。

参考文档

1: 苹果官方文档对于”Build Setting”的介绍
2: iOS开发~制作同时支持armv7,armv7s,arm64,i386,x86_64的静态库.a
3: iOS工程如何支持64-bit
4: Xcode的Architecture和Valid Architecture的区别
5: 64-bit Transition Guide For Cocoa Touch

2017/9/27 posted in  Xcode

xcode4的环境变量,Build Settings参数,workspace及联编设置

一、xcode4中的环境变量

$(BUILT_PRODUCTS_DIR)

build成功后的,最终产品路径--可以在Build Settings参数的Per-configuration Build Products Path项里设置

$(TARGET_NAME)

目标工程名称

$(SRCROOT)

工程文件(比如Nuno.xcodeproj)的路径

$(CURRENT_PROJECT_VERSION)

当前工程版本号

其他:

当编译静态库,设备选模拟器(iPhone 5.0 Simulator),未设置任何Build Settings参数时,默认的基础路径:

/Users/xxx/Library/Developer/Xcode/DerivedData/xxxWorkspace-caepeadwrerdcrftijaolkkagbjf

下面用$()代替上面一长串东东

\((SYMROOT) = \)()/Build/Products

\((BUILD_DIR) = \)()/Build/Products

\((BUILD_ROOT) = \)()/Build/Products

这三个变量中的$()不会随着Build Settings参数的设置而改变

相反,以下可以通过设置而改变

$(CONFIGURATION_BUILD_DIR) = $()/Build/Products/Debug-iphonesimulator

$(BUILT_PRODUCTS_DIR) = $()/Build/Products/Debug-iphonesimulator

$(CONFIGURATION_TEMP_DIR) = $()/Build/Intermediates/UtilLib.build/Debug-iphonesimulator

$(TARGET_BUILD_DIR) = $()/Build/Products/Debug-iphonesimulator

$(SDK_NAME) = iphonesimulator5.0

$(PLATFORM_NAME) = iphonesimulator

$(CONFIGURATION) = Debug

$(TARGET_NAME) = UtilLib

$(EXECUTABLE_NAME) = libUtilLib.a 可执行文件名

${IPHONEOS_DEPLOYMENT_TARGET} 5.0

$(ACTION) = build

$(CURRENTCONFIG_SIMULATOR_DIR) 当前模拟器路径 

$(CURRENTCONFIG_DEVICE_DIR) 当前设备路径 


$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME =

$()/Build/Products/Debug-iphonesimulator

$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) = $()/Build/Intermediates/UtilLib.build/Debug-iphonesimulator

自定义变量

${CONFIGURATION}-iphoneos 表示:Debug-iphoneos

${CONFIGURATION}-iphonesimulator 表示:Debug-iphonesimulator

$(CURRENTCONFIG_DEVICE_DIR) = ${SYMROOT}/${CONFIGURATION}-iphoneos

$(CURRENTCONFIG_SIMULATOR_DIR) = ${SYMROOT}/${CONFIGURATION}-iphonesimulator

自定义一个设备无关的路径(用来存放各种架构arm6/arm7/i386输出的产品)

$(CREATING_UNIVERSAL_DIR) = ${SYMROOT}/${CONFIGURATION}-universal

自定义变量代表的值

$(CURRENTCONFIG_DEVICE_DIR) = $()/Build/Products/Debug-iphoneos

$(CURRENTCONFIG_SIMULATOR_DIR) = $()/Build/Products/Debug-iphonesimulator

$(CREATING_UNIVERSAL_DIR) = $()/Build/Products/Debug-universal

iphoneos5.0下的编译脚本:

xcodebuild -project "UtilLib.xcodeproj" -configuration "Debug" -target "UtilLib" -sdk "iphoneos5.0" -arch "armv6 armv7" build RUN_CLANG_STATIC_ANALYZER=NO  $(BUILD_DIR)="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"

iphonesimulator5.0下的编译脚本:

xcodebuild -project "UtilLib.xcodeproj" -configuration "Debug" -target "UtilLib" -sdk "iphonesimulator5.0" -arch "i386" build RUN_CLANG_STATIC_ANALYZER=NO $(BUILD_DIR)="${BUILD_DIR}"  BUILD_ROOT="${BUILD_ROOT}"

加上下面一句表示输出到文件:

> "${BUILD_ROOT}.build_output"

lipo脚本工具:合并iPhone模拟器和真机的静态类库,生成通用库

`lipo -create -output "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}"         "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}"

意思是:把"\({CURRENTCONFIG_DEVICE_DIR}目录下的.a文件,和\){CURRENTCONFIG_SIMULATOR_DIR}目录下的.a文件合并,

在${CREATING_UNIVERSAL_DIR}目录下,生成两个设备都通用的静态库,

例如:lipo -create -output xy.a x.a y.a

二、xcode4中build Settings常见参数解析

1.Installation Directory:安装路径
静态库编译时,在Build Settings中Installation Directory设置“$(BUILT_PRODUCTS_DIR)”

Skip Install设为YES
Installation Directory默认为/usr/local/lib
因为Build Location默认时,.a文件会放在很长(比如:/Users/xxx/Library/Developer/Xcode/DerivedData/xxxProgram

dalrvzehhtesxdfqhxixzafvddwe/Build/Products/Debug-iPhoneos)的路径下,或是我们target指定的路径
Skip Install如果是NO,可能会被安装到默认路径/usr/local/lib

2.Public Headers Folder Path:对外公开头文件路径
设为“include”(具体的头文件路径为:$(BUILT_PRODUCTS_DIR)/include/xx.h)
在最终文件.a同级目录下生成一个include目录
默认:/usr/local/include
Public Headers Folder Path这个路径就是使用这lib的某工程需要依赖的外部头文件.导入这路径后,#include/import "xx.h"才能看到

3.User Header Search Paths:依赖的外部头文件搜索路径
设置为“$(BUILT_PRODUCTS_DIR)/include”
和2中路径对应

4.Per-configuration Build Products Path:最终文件路径
比如设为“../app”,就会在工程文件.xcodeproj上一层目录下的app目录里,创建最终文件
默认为\((BUILD_DIR)/\)(CONFIGURATION)\((EFFECTIVE_PLATFORM_NAME)
等于\)(BUILT_PRODUCTS_DIR)

5.Per-configuration Intermediate Build Files Path:临时中间文件路径
默认为:\((PROJECT_TEMP_DIR)/\)(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

6.Code Signing Identity:真机调试的证书选择
选一个和Bundle identifier相对应的证书
Library Search Paths:库搜索路径
Architectures:架构,设为 armv6 或 armv7
Valid Architectures:应用框架,可以设为 armv6、 armv7 或i386
Product Name:工程文件名,默认为$(TARGET_NAME)
Info.plist File:info文件路径
Build Variants:默认为normal
Other Linker Flags:其他链接标签
设为“-ObjC”

当导入的静态库使用了类别,需要设为-ObjC
iOS Deployment Target:ios部署对象
比如可以选择设为,ios3到ios5的一种版本
Prefix Header:预编头文件(比如:UtilLib/UtilLib-Prefix.pch)
Precompile Prefix Header:设为“Yes”,表示允许加入预编译头

三、workspace(工作区)

作用:管理多个工程(project),多工程联编

四、workspace多工程联编设置

一、

1.新建一个静态库工程,比如UtilLib,并生成UtilLib.h和UtilLib.m文件

2.选中需要公开的头文件,

把右侧栏的Target Membership中设置为public

或则,选中工程目录target的Build Phases标签的copy headers项,在public中添加要公开的头文件

3.Architectures设为:armv6 armv7

4.Valid Architectures设为:armv6 armv7 i386

5.Build Products Path设为:$(SRCROOT)/../build

6.Per-configuration Build Products Path设为:

\((SRCROOT)/../build/\)(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

7.Per-configuration Intermediate Build Files Path设为:

\((SRCROOT)/../build/\)(TARGET_NAME).build/\((CONFIGURATION)\)(EFFECTIVE_PLATFORM_NAME)

8.设置安装路径:Installation Directory项

9.设置对外公开的头文件路径:Public Headers Folder Path项

10.为静态库添加依赖的shell脚本

选中工程目录target的Build Phases标签,点击由下角的Add Build Phase按钮

在弹出的菜单里选择Add run script项,然后页面中会多出一个Run Script项
在黑框里填写"$SRCROOT/mergeArmSymbols.sh"

建立对此脚本的依赖(编译静态库的后会运行此脚本)

如果编译时设备选的是iphone simulator:

则此脚本会在对应iphone device的产品目录Debug-iphoneos中,生成对device有用的.a静态库,

相反,如果设备选的是iphone device:

则此脚本会在对应iphone simulator的产品目录Debug-iphoneos中,生成对simulator有用的.a静态库

最后,此脚本调用lipo工具,把本工程生成静态库与此脚本生成的静态库合并,生成simulator和device都通用的.a文件

11.具体bash shell脚本如下:

mergeArmSymbols.sh
# Version 2.0 (updated for Xcode 4, with some fixes)

# Author: Adam Martin - http://twitter.com/redglassesapps
# Based on: original script from Eonil (main changes: Eonil's script WILL NOT WORK in Xcode GUI - it WILL CRASH YOUR COMPUTER)
#
# More info: see this Stack Overflow question: http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4

#################[ Tests: helps workaround any future bugs in Xcode ]########
#
DEBUG_THIS_SCRIPT="true"

if [ $DEBUG_THIS_SCRIPT = "true" ]
then
echo "########### TESTS #############"
echo "Use the following variables when debugging this script; note that they may change on recursions"
echo "BUILD_DIR = $BUILD_DIR"
echo "BUILD_ROOT = $BUILD_ROOT"
echo "CONFIGURATION_BUILD_DIR = $CONFIGURATION_BUILD_DIR"
echo "BUILT_PRODUCTS_DIR = $BUILT_PRODUCTS_DIR"
echo "CONFIGURATION_TEMP_DIR = $CONFIGURATION_TEMP_DIR"
echo "TARGET_BUILD_DIR = $TARGET_BUILD_DIR"
echo "SDK_NAME = $SDK_NAME"
echo "PLATFORM_NAME = $PLATFORM_NAME"
echo "CONFIGURATION = $CONFIGURATION"
echo "TARGET_NAME = $TARGET_NAME"
echo "ARCH_TO_BUILD = $ARCH_TO_BUILD"
echo "ARCH_TO_BUILD = $ARCH_TO_BUILD"
echo "ACTION = $ACTION"
echo "SYMROOT = $SYMROOT"
echo "EXECUTABLE_NAME = $EXECUTABLE_NAME"
echo "CURRENTCONFIG_SIMULATOR_DIR = $CURRENTCONFIG_SIMULATOR_DIR"
echo "CURRENTCONFIG_DEVICE_DIR = $CURRENTCONFIG_DEVICE_DIR"

echo "#############Other###########"
echo "BUILD_DIR/CONFIGURATION/EFFECTIVE_PLATFORM_NAME = $BUILD_DIR/$CONFIGURATION$EFFECTIVE_PLATFORM_NAME"

echo "PROJECT_TEMP_DIR/CONFIGURATION/EFFECTIVE_PLATFORM_NAME = $PROJECT_TEMP_DIR/$CONFIGURATION$EFFECTIVE_PLATFORM_NAME"

fi

#####################[ part 1 ]##################
# First, work out the BASESDK version number
#    (incidental: searching for substrings in sh is a nightmare! Sob)

SDK_VERSION=$(echo ${SDK_NAME} | grep -o '.\{3\}$')

# Next, work out if we're in SIM or DEVICE

if [ ${PLATFORM_NAME} = "iphonesimulator" ]
then
OTHER_SDK_TO_BUILD=iphoneos${SDK_VERSION}
ARCH_TO_BUILD="armv6 armv7"
else
OTHER_SDK_TO_BUILD=iphonesimulator${SDK_VERSION}
ARCH_TO_BUILD="i386"
fi

echo "XCode has selected SDK: ${PLATFORM_NAME} with version: ${SDK_VERSION} (although back-targetting: ${IPHONEOS_DEPLOYMENT_TARGET})"
echo "...therefore, OTHER_SDK_TO_BUILD = ${OTHER_SDK_TO_BUILD}"
#
#####################[ end of part 1 ]##################

#####################[ part 2 ]##################
#
# IF this is the original invocation, invoke whatever other builds are required
#
# Xcode is already building ONE target... build ONLY the missing platforms/configurations.

if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Not the root invocation, don't recurse"
else
# Prevent recursion
export ALREADYINVOKED="true"

echo "RECURSION: I am the root... recursing all missing build targets..."
echo "RECURSION: ...about to invoke: xcodebuild -configuration \"${CONFIGURATION}\" -target \"${TARGET_NAME}\" -sdk \"${OTHER_SDK_TO_BUILD}\" -arch \"${ARCH_TO_BUILD}\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO"
xcodebuild -project "${TARGET_NAME}.xcodeproj" -configuration "${CONFIGURATION}" -target "${TARGET_NAME}" -sdk "${OTHER_SDK_TO_BUILD}" -arch "${ARCH_TO_BUILD}" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" > "${BUILD_ROOT}.build_output"
ACTION="build"

# Merge all platform binaries as a fat binary for each configurations.

# Calculate where the (multiple) built files are coming from:
CURRENTCONFIG_DEVICE_DIR=${SRCROOT}/../build/${CONFIGURATION}-iphoneos
CURRENTCONFIG_SIMULATOR_DIR=${SRCROOT}/../build/${CONFIGURATION}-iphonesimulator

echo "Taking device build from: ${CURRENTCONFIG_DEVICE_DIR}"
echo "Taking simulator build from: ${CURRENTCONFIG_SIMULATOR_DIR}"

CREATING_UNIVERSAL_DIR=${SRCROOT}/../build/${CONFIGURATION}-universal
echo "...outputing a universal arm6/arm7/i386 build to: ${CREATING_UNIVERSAL_DIR}"

# ... remove the products of previous runs of this script
#      NB: this directory is only created by this script - it should be safe to delete

rm -rf "${CREATING_UNIVERSAL_DIR}"
mkdir "${CREATING_UNIVERSAL_DIR}"

#
echo "lipo: for current configuration (${CONFIGURATION}) creating output file: ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}"
lipo -create -output "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}" "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}"

#######custom########
#copy universal lib to ../libs
libsDir=../libs
includeDir=../include

rm -rf "${libsDir}"
mkdir -p "${libsDir}"

echo "cp -R ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME} ${libsDir}"

cp -R "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" "${libsDir}"

echo "cp -R ${CURRENTCONFIG_DEVICE_DIR}/include ${includeDir}"

cp -R "${CURRENTCONFIG_DEVICE_DIR}/include" "${includeDir}"

fi
2017/5/18 posted in  Xcode

Xcode环境变量

官网链接:打开

Variable                                  Example
PATH                                      "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
LANG                                      en_US.US-ASCII
IPHONEOS_DEPLOYMENT_TARGET                4.1
ACTION                                    build
AD_HOC_CODE_SIGNING_ALLOWED               NO
ALTERNATE_GROUP                           staff
ALTERNATE_MODE                            u+w,go-w,a+rX
ALTERNATE_OWNER                           username
ALWAYS_SEARCH_USER_PATHS                  YES
APPLE_INTERNAL_DEVELOPER_DIR              /AppleInternal/Developer
APPLE_INTERNAL_DIR                        /AppleInternal
APPLE_INTERNAL_DOCUMENTATION_DIR          /AppleInternal/Documentation
APPLE_INTERNAL_LIBRARY_DIR                /AppleInternal/Library
APPLE_INTERNAL_TOOLS                      /AppleInternal/Developer/Tools
APPLY_RULES_IN_COPY_FILES                 NO
ARCHS                                     "armv6 armv7"
ARCHS_STANDARD_32_64_BIT                  "armv6 armv7"
ARCHS_STANDARD_32_BIT                     "armv6 armv7"
ARCHS_UNIVERSAL_IPHONE_OS                 armv7
AVAILABLE_PLATFORMS                       "iphonesimulator macosx iphoneos"
BUILD_COMPONENTS                          "headers build"
BUILD_DIR                                 "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath"
BUILD_ROOT                                "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath"
BUILD_STYLE
BUILD_VARIANTS                             normal
BUILT_PRODUCTS_DIR                         "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos"
CACHE_ROOT                                 /var/folders/2x/rvb2r9s16mq6r318zxvn0lk80000gn/C/com.apple.Xcode.501
CCHROOT                                    /var/folders/2x/rvb2r9s16mq6r318zxvn0lk80000gn/C/com.apple.Xcode.501
CHMOD                                      /bin/chmod
CHOWN                                      /usr/sbin/chown
CLASS_FILE_DIR                             "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/JavaClasses"
CLEAN_PRECOMPS                             YES
CLONE_HEADERS                              NO
CODESIGNING_FOLDER_PATH                    "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/InstallationBuildProductsLocation/Applications/project.app"
CODE_SIGNING_ALLOWED                       YES
CODE_SIGNING_REQUIRED                      YES
CODE_SIGN_CONTEXT_CLASS                    XCiPhoneOSCodeSignContext
CODE_SIGN_IDENTITY                         "iPhone Distribution"
COMBINE_HIDPI_IMAGES                       NO
COMPOSITE_SDK_DIRS                         /var/folders/2x/rvb2r9s16mq6r318zxvn0lk80000gn/C/com.apple.Xcode.501/CompositeSDKs
COMPRESS_PNG_FILES                         YES
CONFIGURATION                              Distribution
CONFIGURATION_BUILD_DIR                    "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos"
CONFIGURATION_TEMP_DIR                     "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos"
CONTENTS_FOLDER_PATH                       project.app/Contents
COPYING_PRESERVES_HFS_DATA                 NO
COPY_PHASE_STRIP                           YES
COPY_RESOURCES_FROM_STATIC_FRAMEWORKS      YES
CP                                         /bin/cp
CURRENT_ARCH                               armv7
CURRENT_VARIANT                            normal
DEAD_CODE_STRIPPING                        YES
DEBUGGING_SYMBOLS                          YES
DEBUG_INFORMATION_FORMAT                   dwarf-with-dsym
DEPLOYMENT_LOCATION                        YES
DEPLOYMENT_POSTPROCESSING                  YES
DERIVED_FILES_DIR                          "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/DerivedSources"
DERIVED_FILE_DIR                           "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/DerivedSources"
DERIVED_SOURCES_DIR                        "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/DerivedSources"
DEVELOPER_APPLICATIONS_DIR                 /Developer/Applications
DEVELOPER_BIN_DIR                          /Developer/usr/bin
DEVELOPER_DIR                              /Developer
DEVELOPER_FRAMEWORKS_DIR                   /Developer/Library/Frameworks
DEVELOPER_FRAMEWORKS_DIR_QUOTED            "\"/Developer/Library/Frameworks\""
DEVELOPER_LIBRARY_DIR                      /Developer/Library
DEVELOPER_SDK_DIR                          /Developer/SDKs
DEVELOPER_TOOLS_DIR                        /Developer/Tools
DEVELOPER_USR_DIR                          /Developer/usr
DEVELOPMENT_LANGUAGE                       English
DOCUMENTATION_FOLDER_PATH                  project.app/English.lproj/Documentation
DO_HEADER_SCANNING_IN_JAM                  NO
DSTROOT                                    "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/InstallationBuildProductsLocation"
DWARF_DSYM_FILE_NAME                       project.app.dSYM
DWARF_DSYM_FILE_SHOULD_ACCOMPANY_PRODUCT   NO
DWARF_DSYM_FOLDER_PATH                    "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos"
EFFECTIVE_PLATFORM_NAME                    -iphoneos
EMBEDDED_PROFILE_NAME                      embedded.mobileprovision
ENABLE_HEADER_DEPENDENCIES                 YES
ENABLE_OPENMP_SUPPORT                      NO
ENTITLEMENTS_ALLOWED                       YES
ENTITLEMENTS_REQUIRED                      YES
EXCLUDED_INSTALLSRC_SUBDIRECTORY_PATTERNS  ".svn CVS"
EXECUTABLES_FOLDER_PATH                    project.app/Executables
EXECUTABLE_FOLDER_PATH                     project.app
EXECUTABLE_NAME                            project
EXECUTABLE_PATH                            project.app/project
FILE_LIST                                  "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/Objects/LinkFileList"
FIXED_FILES_DIR                            "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/FixedFiles"
FRAMEWORKS_FOLDER_PATH                     project.app/Frameworks
FRAMEWORK_FLAG_PREFIX                      -framework
FRAMEWORK_SEARCH_PATHS                     "\"/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos\" "
FRAMEWORK_VERSION                          A
FULL_PRODUCT_NAME                          project.app
GCC3_VERSION                               3.3
GCC_C_LANGUAGE_STANDARD                    gnu99
GCC_INLINES_ARE_PRIVATE_EXTERN             YES
GCC_PFE_FILE_C_DIALECTS                    "c objective-c c++ objective-c++"
GCC_PRECOMPILE_PREFIX_HEADER               YES
GCC_PREFIX_HEADER                          project/Prefix.pch
GCC_PREPROCESSOR_DEFINITIONS               "NDEBUG DISTRIBUTION_BUILD=1 KK_TARGET=0x000F0"
GCC_SYMBOLS_PRIVATE_EXTERN                 YES
GCC_THUMB_SUPPORT                          YES
GCC_TREAT_WARNINGS_AS_ERRORS               NO
GCC_VERSION                                com.apple.compilers.llvm.clang.1_0
GCC_VERSION_IDENTIFIER                     com_apple_compilers_llvm_clang_1_0
GCC_WARN_ABOUT_RETURN_TYPE                 YES
GCC_WARN_UNUSED_FUNCTION                   YES
GCC_WARN_UNUSED_VARIABLE                   YES
GENERATE_MASTER_OBJECT_FILE                NO
GENERATE_PKGINFO_FILE                      YES
GENERATE_PROFILING_CODE                    NO
GID                                        20
GROUP                                      staff
INPUT_FILE_BASE             Default
INPUT_FILE_DIR              "/Volumes/Development/Project Game/Project-v1/images"
INPUT_FILE_NAME             Default.png
INPUT_FILE_PATH             "/Volumes/Development/Project Game/Project-v1/images/Default.png"
SCRIPT_INPUT_FILE           "/Volumes/Development/Project Game/Project-v1/images/Default.png"
SCRIPT_OUTPUT_FILE_0        "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/DerivedSources/Default.png"

EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES              "*.nib *.lproj *.framework *.gch (*) CVS .svn .git *.xcodeproj *.xcode *.pbproj *.pbxproj"
HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT     YES
HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES YES
HEADERMAP_INCLUDES_NONPUBLIC_NONPRIVATE_HEADERS            YES
HEADERMAP_INCLUDES_PROJECT_HEADERS                         YES
HEADER_SEARCH_PATHS                  "\"/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos/include\" "
ICONV                                /usr/bin/iconv
INFOPLIST_EXPAND_BUILD_SETTINGS      YES
INFOPLIST_FILE                       project/Resources/Info.plist
INFOPLIST_OUTPUT_FORMAT              binary
INFOPLIST_PATH                       project.app/Info.plist
INFOPLIST_PREPROCESS                 NO
INFOSTRINGS_PATH                     project.app/English.lproj/InfoPlist.strings
INPUT_FILE_REGION_PATH_COMPONENT
INPUT_FILE_SUFFIX                    .png
INSTALL_DIR                          "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/InstallationBuildProductsLocation/Applications"
INSTALL_GROUP                        staff
INSTALL_MODE_FLAG                    u+w,go-w,a+rX
INSTALL_OWNER                        username
INSTALL_PATH                         /Applications
INSTALL_ROOT                         "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/InstallationBuildProductsLocation"
JAVAC_DEFAULT_FLAGS                  "-J-Xms64m -J-XX:NewSize=4M -J-Dfile.encoding=UTF8"
JAVA_APP_STUB                        /System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub
JAVA_ARCHIVE_CLASSES                 YES
JAVA_ARCHIVE_TYPE                    JAR
JAVA_COMPILER                        /usr/bin/javac
JAVA_FOLDER_PATH                     project.app/Java
JAVA_FRAMEWORK_RESOURCES_DIRS        Resources
JAVA_JAR_FLAGS                       cv
JAVA_SOURCE_SUBDIR                   .
JAVA_USE_DEPENDENCIES                YES
JAVA_ZIP_FLAGS                       -urg
JIKES_DEFAULT_FLAGS                  "+E +OLDCSO"
KEEP_PRIVATE_EXTERNS                 NO
LD_GENERATE_MAP_FILE                 NO
LD_MAP_FILE_PATH                     "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/project-LinkMap-normal-armv7.txt"
LD_NO_PIE                            NO
LD_OPENMP_FLAGS                      -fopenmp
LEGACY_DEVELOPER_DIR                 /Developer/Library/Xcode/PrivatePlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer
LEX                                  /Developer/usr/bin/lex
LIBRARY_FLAG_NOSPACE                 YES
LIBRARY_FLAG_PREFIX                  -l
LIBRARY_SEARCH_PATHS                 "\"/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos\"  \"/Volumes/Development/Project Game/Project-v1/FlurryLib\""
LINKER_DISPLAYS_MANGLED_NAMES        NO
LINK_FILE_LIST_normal_armv6          "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/Objects-normal/armv6/project.LinkFileList"
LINK_FILE_LIST_normal_armv7          "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/Objects-normal/armv7/project.LinkFileList"
LINK_WITH_STANDARD_LIBRARIES         YES
LOCALIZED_RESOURCES_FOLDER_PATH      project.app/English.lproj
LOCAL_ADMIN_APPS_DIR                 /Applications/Utilities
LOCAL_APPS_DIR                       /Applications
LOCAL_DEVELOPER_DIR                  /Library/Developer
LOCAL_LIBRARY_DIR                    /Library
MACH_O_TYPE                          mh_execute
MAC_OS_X_PRODUCT_BUILD_VERSION       11A511
MAC_OS_X_VERSION_ACTUAL              1070
MAC_OS_X_VERSION_MAJOR               1070
MAC_OS_X_VERSION_MINOR               0700
NATIVE_ARCH                          armv6
NATIVE_ARCH_32_BIT                   i386
NATIVE_ARCH_64_BIT                   x86_64
NATIVE_ARCH_ACTUAL                   x86_64
NO_COMMON                            YES
OBJECT_FILE_DIR                      "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/Objects"
OBJECT_FILE_DIR_normal               "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/Objects-normal"
OBJROOT                              "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath"
ONLY_ACTIVE_ARCH                     NO
OPTIMIZATION_LEVEL                   0
OS                                   MACOS
OSAC                                 /usr/bin/osacompile
OTHER_CFLAGS                         -DNS_BLOCK_ASSERTIONS=1
OTHER_CPLUSPLUSFLAGS                 -DNS_BLOCK_ASSERTIONS=1
OTHER_INPUT_FILE_FLAGS
OTHER_LDFLAGS                        -lz
PACKAGE_TYPE                         com.apple.package-type.wrapper.application
PASCAL_STRINGS                       YES
PATH_PREFIXES_EXCLUDED_FROM_HEADER_DEPENDENCIES  "/usr/include /usr/local/include /System/Library/Frameworks /System/Library/PrivateFrameworks /Developer/Headers /Developer/SDKs /Developer/Platforms"
PBDEVELOPMENTPLIST_PATH              project.app/pbdevelopment.plist
PFE_FILE_C_DIALECTS                  "c objective-c c++ objective-c++"
PKGINFO_FILE_PATH                    "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/PkgInfo"
PKGINFO_PATH                         project.app/PkgInfo
PLATFORM_DEVELOPER_APPLICATIONS_DIR  /Developer/Platforms/iPhoneOS.platform/Developer/Applications
PLATFORM_DEVELOPER_BIN_DIR           /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
PLATFORM_DEVELOPER_LIBRARY_DIR       /Developer/Library/Xcode/PrivatePlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library
PLATFORM_DEVELOPER_SDK_DIR           /Developer/Platforms/iPhoneOS.platform/Developer/SDKs
PLATFORM_DEVELOPER_TOOLS_DIR         /Developer/Platforms/iPhoneOS.platform/Developer/Tools
PLATFORM_DEVELOPER_USR_DIR           /Developer/Platforms/iPhoneOS.platform/Developer/usr
PLATFORM_DIR                         /Developer/Platforms/iPhoneOS.platform
PLATFORM_NAME                        iphoneos
PLATFORM_PREFERRED_ARCH              i386
PLATFORM_PRODUCT_BUILD_VERSION       8H7
PLIST_FILE_OUTPUT_FORMAT             binary
PLUGINS_FOLDER_PATH                  project.app/PlugIns
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR                    YES
PRECOMP_DESTINATION_DIR              "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/PrefixHeaders"
PRESERVE_DEAD_CODE_INITS_AND_TERMS   NO
PRIVATE_HEADERS_FOLDER_PATH          project.app/PrivateHeaders
PRODUCT_NAME                         project
PRODUCT_SETTINGS_PATH                "/Volumes/Development/Project Game/Project-v1/project/Resources/Info.plist"
PRODUCT_TYPE                         com.apple.product-type.application
PROFILING_CODE                       NO
PROJECT                              project
PROJECT_DERIVED_FILE_DIR             "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/DerivedSources"
PROJECT_DIR                          "/Volumes/Development/Project Game/Project-v1"
PROJECT_FILE_PATH                    "/Volumes/Development/Project Game/Project-v1/project.xcodeproj"
PROJECT_NAME                         project
PROJECT_TEMP_DIR                     "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build"
PROVISIONING_PROFILE_REQUIRED        YES
PUBLIC_HEADERS_FOLDER_PATH           project.app/Headers
RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS   YES
REMOVE_CVS_FROM_RESOURCES            YES
REMOVE_GIT_FROM_RESOURCES            YES
REMOVE_SVN_FROM_RESOURCES            YES
RESOURCE_RULES_REQUIRED              YES
REZ_COLLECTOR_DIR                    "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/ResourceManagerResources"
REZ_OBJECTS_DIR                      "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/ResourceManagerResources/Objects"
REZ_SEARCH_PATHS                     "\"/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos\" "
RUN_CLANG_STATIC_ANALYZER            NO
SCAN_ALL_SOURCE_FILES_FOR_INCLUDES   NO
SCRIPTS_FOLDER_PATH                  project.app/Scripts
SCRIPT_INPUT_FILE                    "/Volumes/Development/Project Game/Project-v1/fonts/helvetica-black-hd.png"
SCRIPT_OUTPUT_FILE_0                 "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build/DerivedSources/helvetica-black-hd.png"
SCRIPT_OUTPUT_FILE_COUNT             1
SDKROOT                              /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk
SDK_DIR                              /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk
SDK_NAME                             iphoneos4.3
SDK_PRODUCT_BUILD_VERSION            8H7
SED                                  /usr/bin/sed
SEPARATE_STRIP                       NO
SEPARATE_SYMBOL_EDIT                 NO
SET_DIR_MODE_OWNER_GROUP            YES
SET_FILE_MODE_OWNER_GROUP           NO
SHALLOW_BUNDLE                      YES
SHARED_DERIVED_FILE_DIR             "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath/Distribution-iphoneos/DerivedSources"
SHARED_FRAMEWORKS_FOLDER_PATH       project.app/SharedFrameworks
SHARED_PRECOMPS_DIR                 /Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/Build/PrecompiledHeaders
SHARED_SUPPORT_FOLDER_PATH          project.app/SharedSupport
SKIP_INSTALL                        NO
SOURCE_ROOT                         "/Volumes/Development/Project Game/Project-v1"
SRCROOT                             "/Volumes/Development/Project Game/Project-v1"
STRINGS_FILE_OUTPUT_ENCODING        binary
STRIP_INSTALLED_PRODUCT             YES
STRIP_STYLE                         all
SUPPORTED_DEVICE_FAMILIES           1,2
SUPPORTED_PLATFORMS                 "iphonesimulator iphoneos"
SYMROOT                             "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/BuildProductsPath"
SYSTEM_ADMIN_APPS_DIR               /Applications/Utilities
SYSTEM_APPS_DIR                     /Applications
SYSTEM_CORE_SERVICES_DIR            /System/Library/CoreServices
SYSTEM_DEMOS_DIR                    /Applications/Extras
SYSTEM_DEVELOPER_APPS_DIR           /Developer/Applications
SYSTEM_DEVELOPER_BIN_DIR            /Developer/usr/bin
SYSTEM_DEVELOPER_DEMOS_DIR          "/Developer/Applications/Utilities/Built Examples"
SYSTEM_DEVELOPER_DIR                /Developer
SYSTEM_DEVELOPER_DOC_DIR            "/Developer/ADC Reference Library"
SYSTEM_DEVELOPER_GRAPHICS_TOOLS_DIR "/Developer/Applications/Graphics Tools"
SYSTEM_DEVELOPER_JAVA_TOOLS_DIR     "/Developer/Applications/Java Tools"
SYSTEM_DEVELOPER_PERFORMANCE_TOOLS_DIR   "/Developer/Applications/Performance Tools"
SYSTEM_DEVELOPER_RELEASENOTES_DIR   "/Developer/ADC Reference Library/releasenotes"
SYSTEM_DEVELOPER_TOOLS              /Developer/Tools
SYSTEM_DEVELOPER_TOOLS_DOC_DIR      "/Developer/ADC Reference Library/documentation/DeveloperTools"
SYSTEM_DEVELOPER_TOOLS_RELEASENOTES_DIR   "/Developer/ADC Reference Library/releasenotes/DeveloperTools"
SYSTEM_DEVELOPER_USR_DIR            /Developer/usr
SYSTEM_DEVELOPER_UTILITIES_DIR      /Developer/Applications/Utilities
SYSTEM_DOCUMENTATION_DIR            /Library/Documentation
SYSTEM_LIBRARY_DIR                  /System/Library
TARGETED_DEVICE_FAMILY              1
TARGETNAME                          Project
TARGET_BUILD_DIR                    "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/InstallationBuildProductsLocation/Applications"
TARGET_NAME                         Project
TARGET_TEMP_DIR                     "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build"
TEMP_DIR                            "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build"
TEMP_FILES_DIR                      "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build"
TEMP_FILE_DIR                       "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath/project.build/Distribution-iphoneos/Project.build"
TEMP_ROOT                           "/Users/username/Library/Developer/Xcode/DerivedData/project-dxdgjvgsvvbhowgjqouevhmvgxgf/ArchiveIntermediates/Project Distribution/IntermediateBuildFilesPath"
TEST_AFTER_BUILD                    NO
UID                                 501
UNLOCALIZED_RESOURCES_FOLDER_PATH   project.app    UNSTRIPPED_PRODUCT           NO
USER                         username
USER_APPS_DIR                /Users/username/Applications
USER_HEADER_SEARCH_PATHS     project/libs
USER_LIBRARY_DIR             /Users/username/Library
USE_DYNAMIC_NO_PIC           YES
USE_HEADERMAP                YES
USE_HEADER_SYMLINKS          NO
VALIDATE_PRODUCT             YES
VALID_ARCHS                  "armv6 armv7"
VERBOSE_PBXCP                NO
VERSIONPLIST_PATH            project.app/version.plist
VERSION_INFO_BUILDER         username
VERSION_INFO_FILE            project_vers.c
VERSION_INFO_STRING          "\"@(#)PROGRAM:project  PROJECT:project-\""
WRAPPER_EXTENSION            app
WRAPPER_NAME                 project.app
WRAPPER_SUFFIX               .app
XCODE_APP_SUPPORT_DIR        /Developer/Library/Xcode
XCODE_PRODUCT_BUILD_VERSION  4B110
XCODE_VERSION_ACTUAL         0410
XCODE_VERSION_MAJOR          0400
XCODE_VERSION_MINOR          0410
YACC                        /Developer/usr/bin/yacc
2017/5/18 posted in  Xcode

打包合并通用Framework(模拟器.真机)的脚本

在项目的Build Phases中,新建一个Run Script,输入下面内容:

if [ "${ACTION}" = "build" ]
then
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework

DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework

SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework


if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi

mkdir -p "${INSTALL_DIR}"

cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"

lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"

#open "${DEVICE_DIR}"
#open "${SRCROOT}/Products"
fi
2017/5/18 posted in  Xcode

Xcode 快捷键及代码格式化

按住apple键点击类名就可以定位到这个类中查看相关定义(在日后的开发中我们会经常这么来做,毕竟要记住iOS开发中所有的API是不现实的,有些API我们可以通过这种方法来查找)

  1. 文件
    CMD + N: 新文件
    CMD + SHIFT + N: 新项目
    CMD + O: 打开
    CMD + S: 保存
    CMD+OPt+S:保存所有文件
    CMD + SHIFT + S: 另存为
    CMD + W: 关闭窗口
    CMD + Q :退出Xcode
    CMD + SHIFT + W: 关闭文件

  2. 编辑
    CMD + [: 左缩进
    CMD + ]: 右缩进

CMD+shift+F:项目中查找
CMD+G:查找下一个
CMD+shift+G:查找上一个

Ctrl + F :前移光标
Ctrl + B :后移光标
Ctrl + P :移动光标到上一行
Ctrl + N:移动光标到下一行
Ctrl + A : 移动光标到本行行首 (替换Home键)
Ctrl + E : 移动光标到本行行尾 (替换end键)
Ctrl + T :交换光标左右两边的字符
Ctrl + D:删除光标右边的字符
Ctrl + L : 将插入点置于窗口正中
Ctrl + K :删除本行
Ctrl + . : 参数提示
Tab :接受代码提示
Esc :显示代码提示菜单
CMD + /: 注释或取消注释

CMD + CTRL + LEFT: 折叠
CMD + CTRL + RIGHT: 取消折叠
CMD + CTRL + TOP: 折叠全部函数
CMD + CTRL + BOTTOM: 取消全部函数折叠
CTRL + U: 取消全部折叠

CMD + D: 添加书签

  1. 调试 CMD + : 设置或取消断点 CMD + OPT + : 允许或禁用当前断点 CMD + OPT + B: 查看全部断点

CMD + RETURN: 编译并运行(根据设置决定是否启用断点)
CMD + R: 编译并运行(不触发断点)
CMD + Y: 编译并调试(触发断点)
CMD + SHIFT + RETURN: 终止运行或调试
CMD + Alt + P : 继续(在调试中)
CMD + Alt + 0 :跳过
CMD + Alt + I :跳入
CMD + Alt + T :跳出

CMD + B: 编译
CMD + SHIFT + K: 清理

  1. 窗体
    CMD + SHIFT + B: 编译窗口
    CMD + SHIFT + Y: 调试代码窗口
    CMD + SHIFT + R: 调试控制台
    CMD + SHIFT + E: 主编辑窗口调整

  2. 帮助
    CMD + OPT + ?: 开发手册
    CMD + CTRL + ?: 快速帮助

  3. Xcode6 代码格式化/自动排版:
    选中需要格式化代码 -> Editor -> Structure ->Re-Indent 或者
    选中需要格式化代码 -> 右击 ->选中 Structure ->Re-Indent

    快捷键:Ctrl+a全选->ctrl + i 格式化
    

2017/1/22 posted in  Xcode

多Xcode版本使用xcodebuild命令错误的问题

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance 


在安装cocoapods完毕后,开始安装第三方库的时候,会报这个错。这是因为xcode的路径不对,解决办法如下:

安装 Xcode (从这下载 http://developer.apple.com) 如果你还没有安装的话,
在命令行工具中输入下面的命令:

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

注意: 确保你的xcode和上面的路径一直 ,很有可能是下面这种情况 /Applications/Xcode-Beta.app/Contents/Developer 因为你使用了beta版的xcode。如果你使用了beta版的xcode,就用上面这个路径替代。其他可能,就是你修改了xcode的名字,同理,把路径改对。怎么看呢?从应用程序里看你的xcode程序名就知道了。

多版本的时候需要设置默认的xcode命令行工具的

2016/8/19 posted in  Xcode

断言(NSAssert)的使用

NSAssert和assert是断言,主要的差别是assert在断言失败的时候只是简单的终止程序,而NSAssert会报告出错误信息并且打印出来.所以尽管的使用NSAssert,可以不去使用assert.
iOS中用的最多的是两对断言, NSAssert/NSCAssert 和 NSParameterAssert/NSCparameterAssert. 要知道他们的区别,我们先来看看他们定义.

#if !defined(NS_BLOCK_ASSERTIONS)
#if !defined(_NSAssertBody)
#define NSAssert(condition, desc, ...)  \
  do {              \
  __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
  if (!(condition)) {       \
    [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
    object:self file:[NSString stringWithUTF8String:__FILE__] \
      lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
  }             \
    __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
  } while(0)
#endif
#if !defined(_NSCAssertBody)
#define NSCAssert(condition, desc, ...) \
  do {              \
  __PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
  if (!(condition)) {       \
    [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
    file:[NSString stringWithUTF8String:__FILE__] \
      lineNumber:__LINE__ description:(desc), ##__VA_ARGS__]; \
  }             \
    __PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
  } while(0)
#endif

NSAssert/NSCAssert  两者的

差别通过定义可以看出来, 前者是适合于Objective-C的方法,_cmd 和 self 与运行时有关. 后者是适用于C的函数.
NSParameterAssert/NSCparameterAssert 两者的区别也是前者适用于Objective-C的方法,后者适用于C的函数.
NSAssert/NSCAssert  和 NSParameterAssert/NSCparameterAssert 的区别是前者是所有断言, 后者只是针对参数是否存在的断言, 所以可以先进行参数的断言,确认参数是正确的,再进行所有的断言,确认其他原因.
NSAssert的用法

int a = 4;
NSAssert(a == 5, @"a must equal to 5"); //第一个参数是条件,如果第一个参数不满足条件,就会记录和打印第二个参数
//回记录并打印断言日志    
*** Assertion failure in -[AppDelegate application:didFinishLaunchingWithOptions:], /Users/admin/Desktop/storyboard/storyboard/AppDelegate.m:36
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'a must equal to 5

NSParameterAssert的用法

- (void)assertWithPara:(NSString *)str
{
    NSParameterAssert(str); //只需要一个参数,如果参数存在程序继续运行,如果参数为空,则程序停止打印日志
    //further code ...
}
// 如果str 为空则有如下类似的日志
*** Assertion failure in -[AppDelegate assertWithPara:], /Users/admin/Desktop/storyboard/storyboard/AppDelegate.m:45<pre name="code" class="objc">*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: str'

Xcode 已经默认将release环境下的断言取消了, 免除了忘记关闭断言造成的程序不稳定.
NSAssertionHandler:自定义处理方法,程序不会直接崩溃
NSAssertionHandler实例是自动创建的,用于处理错误断言。 如果 NSAssert和NSCAssert条件评估为错误,会向 NSAssertionHandler实例发送一个表示错误的字符串。每个线程都有它自己的NSAssertionHandler实例。
自定义NSAssertionHandler的子类

@interface MyAssertHandler : NSAssertionHandler
@end
#import "MyAssertHandler.h"
@implementation MyAssertHandler
//处理Objective-C的断言
- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...
{
  NSLog(@"NSAssert Failure: Method %@ for object %@ in %@#%li", NSStringFromSelector(selector), object, fileName, (long)line);
}
//处理C的断言
- (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...
{
  NSLog(@"NSCAssert Failure: Function (%@) in %@#%li", functionName, fileName, (long)line);
}
@end

给线程添加处理类

NSAssertionHandler *myHandler = [[MyAssertHandler alloc] init];
    //给当前的线程
    [[[NSThread currentThread] threadDictionary] setValue:myHandler
                                                   forKey:NSAssertionHandlerKey];
                                                   

实现这些以后,程序能够获得断言失败后的信息,但是程序有可能继续运行,不会强制退出程序.

2016/3/29 posted in  Xcode

简单了解XCode工程模板的创建知识

使用Xcode 6新建工程时,Apple准备了好些模板,这些模板写个Demo还是没有问题的,但是用来组织项目文件还是太弱了,所以情况经常是不得不每次去新建各种目录,这种重复性的劳动一来乏味,二来浪费时间。那么我们能不像创建自己的模板呢?这样新建的工程就能按自己的想法包含各种目录和文件。好消息是可以,坏消息是Apple没有提供相应的文档。虽然没有文档,还是试着来创建一个模板,每次都重复实在太烦(就是这么任性)。

既然没有文档,我们就把Apple的模板复制一份,在它的基础上修改成我们需要的样子。

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project\ Templates/iOS/Application/ 

有iOS所有工程模板。用户自定义的模板建议放到~/Library/Developer/Xcode/Templates/,目录如果不存在就创建。模板至少要包含两部分:一是扩展名为 .xctemplate 的文件夹;二是名称为 TemplateInfo.plist 的属性列表文件。好了,我们来创建一个自定义模板:

// Step 1:
$ mkdir ~/Library/Developer/Xcode/Templates/CocoaBite.xctemplate/

// Step 2:
$ cp /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project\ Templates/iOS/Application/Single\ View\ Application.xctemplate/* ~/Library/Developer/Xcode/Templates/CocoaBite.xctemplate/

现在我们有了一个和Single View Application一样的模板,但这和我们目标还相差很远。接下来我们要做就是修改 TemplateInfo.plist ,让模板为我们做更多准备工作。

Keys Advice
Ancestors No Import settings from another Project Template.
Concrete Recommended Visible or hide Template form New Project Window.
Definitions No Work with workplace. Can write to file example source code.
Description Recommended New Project Window – Project Template Description.
Identifier Yes Project Template Unique Identifier.
Kind Yes XCode Template Kind. Project or File.
Nodes Recommended Create or Copy Files to Project. Copy works
Options Recommended New Project Wizard >> Choose Options for Project. Add Text Fields, Combo Boxes.
Platforms Recommended Set Platform.
Project Yes Set Project Build Settings.
Targets Recommended Set Build Settings, Build Phases for Targets. Link Libraries.

上面列出了TemplateInfo.plist大部分键,详细介绍在 这里

我自己新建的模板主要用到Definitions和Nodes,它们俩组合起来可以控制模板会新建哪些文件。例如我想让模板包含Models目录:

// Step 1:
$ cd ~/Library/Developer/Xcode/Templates/CocoaBite.xctemplate/

// Step 2:
$ mkdir -p Models

// Step 3: 编辑TemplateInfo.plist 如下图所示。

完整的模板放在 这里 Xcode-6-Project-Templates

Reference

Creating Custom Xcode 4 Project Templates
About XCode 4 Project Template (How To Create Custom Project Template)
Xcode-6-Project-Templates
链接

2016/2/19 posted in  Xcode