虚拟机里安装OSX+XCode开发环境

用真机的请直接跳过这个部分。

主要是在VitrualBox里安装mac系统和xcode,参考这篇教程,VirtualBox的版本是4.3.18 r96156,OSX版本是10.11 El Capitan,XCode版本是7.1 (7B91b)。

经过几天的初步使用,感觉用虚拟机开发iOS基本能够满足要求,i5/8g/ssd的配置目测能达到真机70%的开发效率。主要存在的问题是:1)在宽屏上无法满屏,两边会留有黑框,导致鼠标无法顺利停靠在两侧 2)键盘敲击频率过快(约5Hz)时字符乱序出现在编辑器里,例如快速输入“update”可能会得到“updaet” 3)虚拟机里的时钟有可能不准,开发过程中偶尔有问题与此相关,需要考虑在内。

调整分辨率

以管理员方式启动virtualbox和cmd命令行(重要!),执行下面的命令

cd "C:\Program Files\Oracle\VirtualBox"

VBoxManage setextradata "OSXElCapitan" VBoxInternal2/EfiGopMode 3 (注意,参数值 0=640×480, 1=800×600, 2=1024×768, 3=1280×1024, 4=1440×900, 5=1920×1200)

VBoxManage setextradata "OSXElCapitan" "CustomVideoMode1" "1360x768x32" (必须8的整数倍,我这里没有成功)

参考链接:How to Guide for Mavericks VM on Mavericks

通过Virtualbox的远程桌面连接到虚拟机

如果是NAT方式,目标地址是127.0.0.2,用guest里通过ifconfig查看到的10.0.2.xx是不行的。 远程桌面的方式比直接使用虚拟机卡不少,作为开发使用并不实用。

修饰键

苹果键盘与Windows键盘几个修饰键的对应关系如下(在设置里可以改,这里是缺省情况):

Command键(花键 ⌘):对应windows键

Control键(⌃):对应ctrl键

Shift键(⇧):对应shift键

Option键(⌥):对应alt键

两种键盘上这几个修饰键物理布局最大的区别,在于Command键与Option键位置相反,可以去“偏好设置->键盘”里改过来,这样切换两种键盘时就比较容易适应了。

OSX

常用快捷键

官方文档

跳到行首:“Command+左键”(Home键是跳到页首)

结束任务:Command+Option+Esc

XCode7快捷键

代码辅助:control+.

打开/关闭左侧Navigator边栏:Command+0(数字0)

打开/关闭右侧Utilities边栏:Option+Command+0(数字0)

快速打开文件(Open Quickly):Shift+Command+O(字母O)

转到定义(Go to Definition):Command+鼠标点击,或Option+Command+J

自动格式化代码:Control+I(需要先全选,否则只格式化当前行)

调整模拟器大小:Command+3(50%)

Swift2

一些教程

官网:swift.org

官方文档:The Swift Programming Language, 中文版

斯坦福免费视频公开课:Developing iOS 8 Apps with Swift中文翻译

国内视频教程:精通iOS移动开发(Xcode7&Swift2)(免费,内容比较初级)

cocoachina专题:从今天开始学习Swift(大量资源链接)

常量

多数项目里都需要一些常量,java里通常定义在interface里,用swift时可以定义在一个struct里,作为静态的存储成员(static let)。

类型转换

Double转Int: Int(myDouble)

保留小数点位数

方法1(3.1415926->3.14, 3->3.00):

let i = 3.1415926
let str = NSString(format:"%.2f",i)
print("\(str)") //will output 3.14

方法2(3.1415926->3.14, 3->3):

let nf = NSNumberFormatter()
nf.numberStyle = NSNumberFormatterStyle.DecimalStyle
nf.maximumFractionDigits = 2
print("\(nf.stringFromNumber(3.1415926))") //will output 3.14

时间

NSDate:相当于java.util.Date,获得系统当前时间直接用NSDate()

NSTimeInterval:等同于double,NSDate.timeIntervalSince1970可以得到自1970年的秒数(注意不是java里的毫秒数)

NSDateFormatter:用来帮助在String与NSDate类型之间做转换 参考

官方文档页

嵌套struct

注意一个地方,例如struct A里定义了struct B,实例化A时,必须先执行a.property1 = value1以后再执行b.a=a,否则会发现b.a.property1=nil。

UIView

所有控件的基类。

frame与bound的区别:frame是view的边界,bound是view可以绘制的区域(bound是可以超出frame范围的)。参考链接1 参考链接2

UITableView

基本使用:可以用ViewController里放TableView,也可以直接用TableViewController,参考How to make a simple tableview with iOS 8 and Swift

使用TableViewController时显示Activity Indicator View(菊花)有问题,不太完美的解决方案见:UITableView Activity Indicator the Apple way,或使用第三方实现,例如下面会提到的SVProgressHUD

处理cell点击事件,实现tableView:didSelectRowAtIndexPath方法即可,注意看清楚别实现成tableView:didDeselectRowAtIndexPath。 参考链接

点击cell跳转(假设从A跳到B):在storyboard里,直接从A的cell到B拖拽创建一个show类型的segue并指定此segue的identity,在A代码里实现forSegue方法将要传的参数赋值给B即可。

UICollectionView

相当于Android里的GridView,可以显示多列数据,只是没有cell的默认实现,也就是必须使用自定义cell。

要让每个cell的宽度恰好等于collection view的一半,可通过实现下面的方法实现(参考链接):

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
  return CGSize(width: CGFloat(self.view.frame.size.width / 2), height: self.view.frame.size.height / 3)
}

AutoLayout

假设有一个长宽都是150的image view,里面要加载一个网络图片(尺寸未知),要求网络图片能够完整显示在image view里且最长边与image view的边长相等,如何实现呢?参考以下链接:

被这个问题困扰了一段时间,以上几个链接提供的方法都没成功。后来发现,在使用autolayout的情况下,控件的width和height应该通过constraint指定(见下图),配合contentMode=scalefit即可解决。

顺便提一句,在storyboard里看到的控件位置并不一定是运行时的位置,因为autolayout情况下只考虑constraint,运行时的位置在storyboard里以橘黄色虚线表示(见下图)。

Storyboard还提供了多设备预览功能,使用方法是“打开 Main.storyboard ,然后选择 View\Assistant Editor\Show Assistant Editor ,这时编辑区会分隔为两部分。再点击顶部导航栏中的 Automatic ,在弹出菜单中选择 Preview ,最后选择 Main.storyboard (Preview) ... 点击预览界面左下角的 + 按钮,会弹出当前storyboard文件支持的各种尺寸的设备”(来源

关于"Relative to margins"选项,在xcode7里这个选项是默认勾选的,每个view默认有宽度为8的margin,可以通过“Editor->Canvas->Show Layout Rectangles”菜单项打开,margin位置显示为蓝色细线。举例来说,当勾选了“Relative to margins”选项后,如果一个子view的leading space to 父view是0,运行时会看到子view距离父view的边界还有8的空白区域(效果相当于android里给父view设置了8的padding)。这个缺省margin值可以通过下面的方法设置:

self.rootView.layoutMargins = UIEdgeInsetsMake(0, 50, 0, 0);

参考链接:

从此爱上iOS Autolayout

Layout Margin Comes With iOS8

第三方依赖包

依赖包管理/Carthage

先安装Homebrew(osx的包管理工具),然后通过Homebrew安装Carthage(比cocoapods灵活,去中心,只支持ios8和以上版本)。

在工程目录下新建“Cartfile”文件,并填写要依赖的包,然后执行carthage update命令,此时如果提示“unable to find utility "xcodebuild", not a developer tool”,可使用"sudo xcode-select --switch"命令解决,这样就下载了依赖包。为了让xcode能用到carthage编译的framework,先从Finder把刚才生成的.framework文件拖到工程的General -> Linked Frameworks and Libraries区域(在Navigator里点击工程根目录即可看到)里,然后在Build Phases里添加一个新内容是“/usr/local/bin/carthage copy-frameworks”的Run Script,并在Input Files里增加所需的编译后的依赖包如“$(SRCROOT)/Carthage/Build/iOS/SwiftyJSON.framework”。 参考Carthage的Getting Start

经测试还需要在工程的Build Setting -> Framework Search Path里添加“$(SRCROOT)/Carthage/Build/iOS”,否则build会失败。参考资料

依赖包管理/CocoaPods

有些第三方依赖只支持cocoapods,所以也要装一个cocoapods。cocoapods的资料比较多,例如这篇,也比较容易安装使用。一个需要注意的问题是,执行pod setup命令后提示Setting up CocoaPods master repo要等很久,大约1小时。

在swift文件里使用object-c开发的库,需要借助一个bridging文件,通常名称是“项目名-Bridging-Header.h”。可以让xcode生成这个文件,方法是在工程里创建一个空的Objective-C文件,最后一步时xcode会提示是否创建bridging文件,点YES然后再删掉这个空文件即可。在bridging文件里使用类似#import <AFNetworking/AFNetworking.h>的方式包含依赖包。

如果pod install执行很慢,可能是pod更新spec时被墙,可以加--no-repo-update参数。参考链接

pod install --verbose --no-repo-update

还可以改用国内镜像,例如:

pod repo remove master
pod repo add master https://git.oschina.net/6david9/Specs.git
pod reap list

无法安装Realm:ios-charts依赖Realm,安装时很慢(有时等待数小时无果,有时提示SSL Handshake错误),其实真正原因是Realm/core所在服务器被墙。可以通过1)使用VPN解决,或2)手工下载安装core(参考Download core 0.96.0 failed),或3)使用国内镜像(如果已经下载core失败过需要清除缓存,参考Core occasionally cannot be downloaded from China)。

HTTP请求/远程图片

据说SwiftHTTP是个坑,暂时绕开,使用系统提供的NSURLSession简单封装一下。使用方法参考链接

iOS9里默认要求所有http请求都使用https,如果一定要用http,在工程的info.plist里修改“App Transport Security Settings -> Allow Arbitrary Loads”为true。

AFNetworking,功能强大且被广泛使用的Http库,还带有异步加载/缓存远程图片的功能;对应Swift版本的名称是Alamofire

JSON

暂时使用SwiftyJSON,感觉还好,使用举例:let json1 = JSON(["param1":1])。

下拉刷新/上拉翻页

下拉刷新:iOS8起内置了UIRefreshControl可以方便的实现下拉刷新功能 用法

上拉翻页/加载更多:暂时没有发现原生的简便方法实现,第三方库倒是比较多,例如SVPullToRefreshMJRefresh

进度条

由于TableViewController显示Activity Indicator有问题,目前在用SVProgressHUD作为替代方案。

折线图/饼图

ios-chart,项目主页的Usage里说了一堆步骤其实都是针对手动安装的,如果用cocoapods直接编辑Podfile添加pod 'Charts'再执行pod install即可,bridge都不用改,在自己的.swift文件里import Charts就可以使用了。不过我遇到一个编译问题,ChartPlatform.swift这个文件编译不过去,自己在文件结尾加了个空行解决。使用方面,一个比较好的教程见这个链接

经过试用,发现ios-charts画时序图(timeseries)比较麻烦,要自己做一些计算(参考)。

替代方案:Core Plot(侧重科学绘图),ios-linechart(使用简单),JBChartView(来自Jawbone),BEMSimpleLineGraph(使用简单)。

(未完,持续补充中)

Swift开发iOS应用过程中的问题和解决记录的更多相关文章

  1. 驰骋工作流引擎-CCMobile与安卓、IOS集成过程中的问题与解决方案

    CCMobile与安卓.IOS集成过程中的问题与解决方案 前言: CCMobile(2019版本)是CCFlow&JFlow 的一款移动端审批的产品.系统基于mui框架开发,是一款可以兼容An ...

  2. ios逆向过程中lldb调试技巧

    在ios逆向过程中,善于运用lldb,会给逆向带来很大的方便 一般的命令: 1.image list -o -f  看看各个模块在内存中的基址 2.register read r0  读取寄存器r0的 ...

  3. win7 安装过程中遇到的错误解决方法

    win7 安装过程中遇到的错误解决方法 windows安装无法继续.若要安装windows 请单击 确定 重新启动计算机: 当 出现如上提示的时候,按下shift+f10 会打开命令窗口,进入到C:\ ...

  4. kakfa源代码开发环境搭建过程中的错误处理

    在window上搭建kafka的源代码开发环境,主要参考如下的blog: http://www.bubuko.com/infodetail-695974.html    << Window ...

  5. npm使用过程中的一些错误解决办法及npm常用命令

    node,npm在前端开发流程中提供了非常完善的自动化工具链,但是同样由于其复杂性导致有很多奇奇怪怪的问题.本文将记录使用过程中出现的一些问题及其解决方法备案. 国内由于gfw问题,导致很多国外的网站 ...

  6. 【转】npm使用过程中的一些错误解决办法及npm常用命令

    原文 node,npm在前端开发流程中提供了非常完善的自动化工具链,但是同样由于其复杂性导致有很多奇奇怪怪的问题.本文将记录使用过程中出现的一些问题及其解决方法备案. 国内由于gfw问题,导致很多国外 ...

  7. gitlab使用过程中的需求与解决

    序言 在git使用过程中发现指令实在太多,就算记忆后不长用的话很快也会忘记掉,所以编写本文的初衷是为了记录在使用git指令的过程中所遇到的需求与解决方法,毕竟使用git的需求也就那么一些,范围不大,所 ...

  8. npm使用过程中的一些错误解决办法及npm常用命令和技巧

    node,npm在前端开发流程中提供了非常完善的自动化工具链,但是同样由于其复杂性导致有很多奇奇怪怪的问题.本文将记录使用过程中出现的一些问题及其解决方法备案. 国内由于gfw问题,导致很多国外的网站 ...

  9. 编译recovery及过程中的部分错误解决

    你必须使用32位或64位Ubuntu系统,关于如何建立编译环境和同步源码的指导,请自己查找有关指导的文章. 1, 安装所需要的包 2, 建立编译的环境,并同步CWM所需的源码,CyanogenMod源 ...

随机推荐

  1. log4net记录日志到数据库自定义字段

    假设数据库中有如下自定义字段:   1.根据自定义字段定义日志信息对象     public class MessageLog     {           /// <summary> ...

  2. 使用Servlet实现图片下载

    package chensi.com; import java.io.FileInputStream; import java.io.IOException; import java.net.URLE ...

  3. 如何在asp.net中使用多线程及队列,异步处理一个耗时的任务(原创)

    最近想在使用.net 的队列处理一些耗时的工作.经过考虑,需要先设计一个类,类中包含一个静态的队列.主要是写队列和读取队列. public class PaperCalculator { // 用于存 ...

  4. 9x25 串口映射

    duart       /dev/ttyS0            /dev/ttyS0 usart1    /dev/ttyS2 /dev/ttyS1 usart2    /dev/ttyS3    ...

  5. Til the Cows Come Home

    Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...

  6. 【洛谷P1080】国王游戏

    我们按照左右手数的乘积升序排序,就能使最多金币数最小了 为什么呢? 我们知道: 1)如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人 2)假设相邻的两个人i, i + 1.设A[i] B ...

  7. Jade之Mixins

    Mixin mixin允许我们对某一个块的重复使用,类似于函数. 用法:首先声明mixin,然后使用(在mixin名字之前加+即可以使用)即可. 最简单的mixin jade: //- 声明 mixi ...

  8. Subsets 子集系列问题 leetcode

    子集系列问题: Coding 问题中有时会出现这样的问题:给定一个集合,求出这个集合所有的子集(所谓子集,就是包含原集合中的一部分元素的集合). 或者求出满足一定要求的子集,比如子集中元素总和为定值, ...

  9. Java里的if else嵌套语句例子

    import java.util.Scanner; public class if_else3 { public static void main(String[] args) { Scanner s ...

  10. 看起来像一个输入框的input,实际上是有两个input

    看起来像一个输入框的input,实际上是有两个input