PresentViewController提供一个半透明的viewcontroller

相信不少人的项目里都会有这样一个需求,例如做个自己的actionsheet,或者弹出个自己做的分享页面,苹果自己的办法就是用presentviewcontroller提供一个新的controller,例如alertController。而当我们需要自己做的时候,就可以有两种方法,一种是addSubview,同时利用动画来实现,这样也可以做到很不错的效果,但毕竟不是官方做法,所以这里不做详解,我们主要来讨论下官方用法,利用presentViewController的方法来展示一个新的controller。

很多人可能会直接就这样写了:

let vc = whatEverNameViewController()
vc.view.alpha = 0.5
self.presentViewController(vc, animated: true, completion: nil)

这样很简单,你会发现你得到了一个黑屏,于是你转而Google一下,发现绝大多数解决方法都是说利用storyboard ID来声明VC,当然这样确实是一个解决办法,但如果就是没用storyboard而是用手写的VC呢,于是继续Google,发现要设定modalPresentationStyle,于是你手指翻动,加上了这样一句:

self.modalPresentationStyle = .CurrentContext

加上之后跑一遍,结果只有动画过程中半透明,动画结束了还是黑屏,原来,这个只是IOS7之前的写法,在IOS8及以后的版本中,apple为了配合自己的alertController,将这个方法从rootViewController中移到了展示的controller中,所以正确的写法现在变成了这样:

let vc = whatEverNameViewController()
vc.view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
vc.modalPresentationStyle = .OverCurrentContext
vc.modalTransitionStyle = .CoverVertical
self.presentViewController(vc, animated: true, completion: nil)

注意到一个小小的不同了么?是的,不要直接设定view的alpha值,这样会导致所有的subview都变得透明,而应该是backgroundColor的alpha值,这样subview便不会受到影响。
至于怎么返回上一个VC,其实只要使用dismissViewControllerAnimated这个方法就可以,加个tap手势或者加个按钮事件都可以

Swift 2.2 is available now!

在这个让人略失误的let us loop you in 发布会之后,苹果开放了包含Swift 2.2 版本的Xcode7.3版本的下载。这是Swift开源之后的第一次发布官方版本,这也是第一个包含非Apple官方程序员贡献者的版本,根据Release notes的统计,该版本共包含了212位非Apple官方程序员的贡献,包括但不限于以下几个:

虽然在之前的snapshot版本中,swift2.2包含了swift自己的包管理工具Swift Product Manager(以下称SPM),但是包含在Xcode7.3中的swift2.2并未包含SPM工具,想使用最新的swift toolchain管理包的同学只能去下载swift3.0的snapshot了

有关Swift2.2版本方面的代码方面的改变:

  • 移除C语言风格的for循环,同时移除++和–操作符,包括前置与后置,将在3.0版本中彻底停用
  • 函数方法将不能直接声明为柯里化参数列表, 而是需要返回一个相同参数的函数方法.

这里用代码举例解释一下:

func doGET(url: String, completionHandler: ([String]?, NSError?) -> ()) {
    // do a GET HTTP request and call the completion handler when receiving the response
}
func completionHandler(results: [String]?, error: NSError?) {
    self.results = results
    self.resultLabel.text = "Got all items"
    self.tableView.reloadData()
}

func getAll() {
    doGET("http://blog.swiftflamel.com", completionHandler)
}

这样的写法在swift2.1及以前都是被认同的,但是在2.2版本中,这种写法将无法被编辑器识别,将直接报错,而之后只能使用如下这种写法:

func completionHandler(text: String) -> ([String]?, NSError?) -> () {
    return {results, error in
        self.results = results
        self.resultLabel.text = text
        self.tableView.reloadData()
    }
}
func getAll() {
    doGET("http://blog.swiftflamel.com", completionHandler("Got all items"))
}

而在swift2.1版本及以前,以上的写法还可以用写法上更简单的柯里化函数来写:

func completionHandler(text: String)(results: [String]?, error: NSError?) {
    self.results = results
    self.resultLabel.text = text
    self.tableView.reloadData()
}

而如今柯里化函数也不被允许了,会被编辑器要求替换为第二种方法的写法

  • 将函数选择器(selectors)的用法由原来的Selector(“doSomething”)或者大多数像我一样的直接”doSomething”改为#selector(doSomething),并且现在会在编译时检查这一写法
  • 大部分关键词现在都可以被用来作为函数的参数名
  • 现在在协议(protocol)中可以声明联合类型(Associated types)了,任何遵守协议的类或结构体可以定义具体的类型

关于Associatedtypes的解释:意思就是现在你可以通过“associatedtype”关键词在协议中声明一个(或多个)变量,这个变量的具体类型将在继承了该协议的类或结构体中来定义,来看一下官方的例子:

protocol Container {
    associatedtype ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}
//使用的时候就这样:
struct IntStack: Container {
    // original IntStack implementation
    var items = [Int]()
    mutating func push(item: Int) {
        items.append(item)
    }
    mutating func pop() -> Int {
        return items.removeLast()
    }
    // conformance to the Container protocol
    typealias ItemType = Int
    mutating func append(item: Int) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Int {
        return items[i]
    }
}

这样应该就能大概明白associated type的用法了吧,更多详细深层的用法可以去查看官方文档:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html

有关Xcode:

2.pic

Editor里只有这一条,但我相信这会让绝大多数iOS开发者非常兴奋了,对于升级为对Release notes不感兴趣的开发者,相信它们打了几个代码下去之后就会发现这令人惊喜的改变,不错,现在的Xcode自带的代码补全也加入了模糊匹配功能,而且表现很优秀,Fuzzy Autocomplete是一个非常优秀的代码补全插件,但是我在用了一段时间之后不得已从我的Xcode卸载了它,因为当应用的文件规模变大时它的性能需求也变得非常高,我最新的15”rMbp也会被弄得异常卡顿,甚至让我有了使用Windows系统的感觉。但最新版Xcode的这个自动补全功能使用起来非常顺畅,在大项目中依然不会卡顿,立刻去升级Xcode7.3吧,享受一下。

 

版权所有,转载请先联系flamelswift@gmail.com

提交ITC收到邮件提示’Invalid Swift Support’的解决方法

第二个app完工了,上传ITC的时候却无论上传几次都会直接被ITC邮件否决,提醒我’Invalid Swift Support‘,具体是这样:

The files libswiftContacts.dylib don’t match /Payload/My.app/Frameworks/libswiftContacts.dylib. Make sure the files are correct, rebuild your app, and resubmit it. Don’t apply post-processing to /Payload/My.app/Frameworks/libswiftContacts.dylib

当然之后就各种Google各种找,最后发现貌似是CocoaPods的问题

https://github.com/CocoaPods/CocoaPods/issues/4188

然后转到这个问题:

https://github.com/CocoaPods/CocoaPods/pull/4221

对于不想看英文的读者,我来总结一下:

最开始的解决方案是开启bitcode,因为bitcode较新(以上issue的时间)的缘故,大部分第三方库还没有支持bitcode,开启bitcode会使app无法build,但是到了现在我的app中引入了6个比较著名的第三方库,都已支持了bitcode,开启了bitcode之后我再上传ITC就已经build 的通过了,所以如果项目比较新,第三方库也以swift为主的可以考虑这个方法,顺便一提这个问题出现的原因就是因为引入的第三方库里面有以swift语言写的库才会出现。

以下是正确的解决方法(更新:我自己验证并没有成功):

开启Pod.project的build settings, 找到Embedded Content Contains Swift Code 由No改为Yes,同时更新CocoaPods到更新的版本(要高于0.39.0的beta5)

—————————Update————————————————————

不开启bitcode的解决方法:

更新了cocoapods之后,上述选项再改成YES直接会导致在上传ITC的时候就报错:

contains disallowed file Frameworks:xxxxxxxxx

这种时候可以这样,Pods —> Targets Supports Files —> Pods-yourappname —>  -Frameworks.sh, 找到这一条注释:

# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.

把这条注释到下一条注释之间的代码块注释掉(注意有一个 ‘}’ 不要注释掉),然后关闭Pods的Embedded Content Contains Swift Code,关闭bitcode,跑一下确认程序能正常运行,然后就可以archive上传了

Swift项目通过CocoaPods引入第三方库出现’No such module of xxx’的问题

CocoaPods是一个很方便的第三方库管理工具,但是swift似乎和它兼容的不是那么完美,尤其是引入OC库的时候,我自己经历了许多次引入了第三方库却显示”No such module of XXXX”的无法import的情况,下面说一下几个常用的解决办法

1、Build Active Architecture

进入Targets->Your project->Build settings-> Build Active Architecture Only->

将debug和release下面都改成Yes,然后build

1.pic

2、Link Binary With Libraries

如果上面一种方法不解决问题,那么尝试下如下方法:

进入Targets->Your project->Build phases->Link Binary with Libraries

看看下面是否正确添加了一个Pods.framework链接,如果没有,那么加上

W1F0V

3、Configurations

如果上面两个方法都没解决,那么尝试方法三

进入Project > Info > Configurations

J3MLi

可以看到应该是这样的,如此,把带Tests后缀的项也改成和无Tests后缀的项的样子,添加Configurations set,然后再次尝试build

如果以上三种方式都没有办法,那么就只好放弃使用CocoaPods,手动添加第三方库然后通过bridge header链接吧

云服务器安装WordPress教程完整版(配置公钥+环境安装+数据库+WordPress)

折腾了近一天之后,终于重做好了服务器系统和web环境,重新安装好了WordPress,然后才发现原来WordPress是这么好的东西,完全没有以前各种后台503错误的情况,因为怀疑是服务器规格太低升级了服务器配置,结果发现根本内存和cpu使用率都很少上10%,可是还是一安插件就503,一开主题就503,最终求助了大神,才知道原来WordPress最好不要直接部署在服务器上,而是在服务器新建个虚拟主机之后再安装到虚拟主机上,下面就给大家分享下全部的过程:
*以下全部教程均在Mac上实现,Windows用户仅供参考
1、配置服务器公钥登录
在全部过程做完之后,我们会经常直接登录服务器用命令行来处理问题,所有为服务器配置公钥登录能大大节省我们的时间,下面我们来配置一下。
(1)在本地机器创建公钥
打开万能的终端,输入如下代码:

ssh-keygen -t rsa -C  'your email@domain.com'

如果提示你已存在,则输入n→回车→进行下一步,否则就无视输出一路回车就好。关于上面代码的解释:-t 指定密钥类型,默认即 rsa ,可以省略 -C 设置注释文字,比如你的邮箱,domain.com就是你服务器的网址或ip地址
(2)将公钥复制到ssh服务器
将前一步骤生成的公钥~/id_rsa.pub文件,复制到ssh服务器对应用户下的~/.ssh/authorized_keys文件

scp ~/.ssh/id_rsa.pub username@hostname:~/

#将公钥文件复制至ssh服务器

ssh username@hostname

#使用用户名和密码方式登录至ssh服务器

mkdir .ssh

#若.ssh目录已存在,可省略此步

cat id_rsa.pub >> .ssh/authorized_keys

#将公钥文件id_rsa.pub文件内容追加到authorized_keys文件
(3)自定义别名(alias)登录
进行完成以上步骤后,我们就可以在终端里只用一行命令登录服务器啦

ssh username@hostname

其中username为服务器用户名,hostname为服务器ip
但其实这样每次登录我们还是需要输入一遍服务器ip,还是略显麻烦,其实ssh本身也提供了一种快捷的方式来解决这个问题,只要我们在ssh的配置信息中写入服务器信息即可

vim ~/.ssh/config

#如果没有该文件,执行如下语句创建一个:

touch ~/.ssh/config

在vim模式下编辑该文件,添加如下信息:
Host alias #选个你想要的别名
HostName hostname #替换为你的ssh服务器ip或domain
Port port #ssh服务器端口,默认为22
User user #ssh服务器用户名
IdentityFile ~/.ssh/id_rsa #第一个步骤生成的公钥文件对应的私钥文件
保存文件退出
*对于不熟悉或不懂vim编辑模式的读者,简要说明一下,进入vim格式后按i键进入编辑模式,输入上述信息,完毕后按esc键,输入:wq,回车,这样文件就保存完毕了
这样就可以直接用如下命令登录服务器了:

ssh alias

2、安装系统及web环境
我个人十分推荐使用如下的一键安装包,对于新手来说非常快捷简便
http://oneinstack.com/install
这里面已经写了非常详细的教程,我只说我遇到的问题
(1)系统及web环境
①我个人选择的是lnmp,Nginx相对于Apache的优势可以自行Google,此处不再赘述
②唯一要注意的是不同软件之间的兼容性问题,我本身选择的是MySQL5.6搭配PHP5.5,运行良好,但其他各个不同版本之间是否会有冲突问题并不清楚,如果想安装其他版本,建议先行Google兼容性
③剩下一切都仔细看提示,提示怎么写怎么选择就好
(2)添加虚拟机
在我添加虚拟机的过程中,在设置完网站根目录之后,会有提醒我:chown: 无效的用户: xxx xxx,然后到最后添加虚拟机就会失败,搜索了一番得到如下解决办法:
首先,在服务器中执行如下两行代码,xxx为刚刚提示的无效的用户中提到的

[root][~]# cat /etc/passwd | grep xxx
[root][~]# cat /etc/group | grep xxx

上面一行是检查用户是否存在,下面一行是检查用户组是否存在,存在的话都会返回一行代码,不存在则无反应,如果不存在用户,则执行如下命令:

[root][~]# useradd xxx -g xxx

如果用户组不存在则执行如下命令:

[root][~]# groupadd xxx

如果都不存在,则先执行添加用户组,再添加用户到用户组,我遇到的问题是用户组不存在,所以执行完第二条语句之后重新添加虚拟机成功
(3)添加FTP账号
此处未遇到问题,按照教程添加即可
至此,系统及web环境就已经安装配置完毕了,下面进入WordPress安装的部分
3、MySQL数据库创建
因为我在安装web环境时就按照推荐的并没有安装PHPmyadmin,所以数据库创建需要用命令行完成,如果你选择安装了PHPmyadmin,那么可以直接安装WordPress官网上的教程执行,下面我会说得比较详细,为了那些没有接触过MySQL的读者,熟悉者可以直接看代码部分,安装了PHPmyadmin的读者可直接跳过
首先在服务器输入以下指令:

mysql -u root -p

接下来会提示你要输入密码,由于MySQL刚刚创建,所以没有密码,直接回车进入MySQL
对于想修改MySQL密码的,可以执行如下语句:

mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');

所有语句后面都应该有’;’,不要忘记
然后我们创建WordPress数据库和用户

mysql>create database databasename;
mysql>GRANT ALL PRIVILEGES ON databasename.* TO username@hostname IDENTIFIED BY "password";
mysql>FLUSH PRIVILEGES;

其中数据库名和用户名自己起,建议为WordPress,hostname一般为localhost,如果出现如下情况:
ERROR 1372 (HY000): Password hash should be a 41-digit hexadecimal number;
这说明MySQL不允许明文输入密码,输入如下语句获取你想要的密码对应的字符串:

mysql>SELECT PASSWORD('yourpassword')

得到的字符串再重新执行上述代码,成功后MySQL的WordPress数据库就创建完毕了
4、WordPress安装
这里面大概也没什么可以说得了,按照官网的流程走就可以了,wp-config.php配置就填刚刚创建数据库你填的那些,用ftp客户端连接到在步骤2的第三步创建的FTP账号,应该能看到刚刚创建好的虚拟主机的文件夹(名字也是你自己命名的),将下载好的WordPress文件夹下所有文件复制到该目录下,注意是文件夹下所有文件,不要连目录一起复制,除非你不想将WordPress放在网站根目录下,之后就可以登录网站进行安装了,如果你的网址还是无法连接到服务器,那说明你的服务器安装之后没有启动,不要看阿里云上写着你服务器运行中就真是运行中了,要去服务器手动启动。
一样还是ssh alias进入服务器,输入如下代码:

service nginx start
service mysqld start
service php-fpm start

我是安装了lnmp,所以需要这样启动,如果安装了别的组合,还是去安装教程那个页面,找到“如何管理服务”项,启动对应的服务就好。
至此,所有步骤完毕,像我一样享受WordPress带来的方便又高效的博客服务吧
如有其它问题,可在评论中讨论

Programmer or coder?

今天CEO带了他的侄子来找CTO聊他的人生出路问题,一个学计算机的大三学生,C语言大三才终于过了,现在突然觉得也许以后可以进入这一行来工作,家里是想让他进入银行工作,他是想自己凭年轻闯一闯。结果CTO说了无数得话和他说这一行不好做,希望他去银行,最不济先找个技术大厂实习一下看看是不是适合这一行。我在旁边也听了很多,我的CTO是个技术不错的人,但相较于BAT的大牛,自然有一些差距,听到这样一个技术很好的人谈论这个行业的严肃性,我也得思考思考自己的人生了。所以我们今天就来聊聊究竟应不应该进入IT这个行业。

在聊天过程中那个男孩说了一句话:这个行业是金饭碗。很遗憾,现在恐怕已经不是这样了,我本身的大学是所谓的信息黄埔,但身边的同学在找工作时候仍然遇到了各种各样的困难,因为我剑走偏锋,选择了swift作为主攻方向,所以实习和工作都找得相对轻松,可是真那些写JAVA的同学,做网页的同学,很难找到。因为所有的学校教的都是这些,大家出去拿出的都是一样的简历,而且丝毫经验没有,真的是很难找。是,现在这个行业的薪资水平普遍比较高,但是真正有多少人是热爱这个行业的?一段代码拿出来,大牛可以读懂,水平一般的人也能读懂,代码都是一样写,那你凭什么和别人不一样?现在这个行业中,绝大多数的程序员最后都将自己的工作变成了重复性的工作,日复一日的敲敲敲,就像最后我向那个男孩发问的一样,如果是这样,你会高兴么?你会有成就感么?男孩当时摇了摇头,我相信问所有人,几乎所有人都会摇头。可是事实就是这样,大多数人脑子一热就进来了,然后变成了一个coder,只是码代码而已。如果真的只是这样,其实不进来这个行业也罢,反正也不快乐,何必还要压力这么大呢?

我最开始想来学iOS开发,就像我的CTO总结的绝大多数的AppStore开发者都是看到了那些一夜暴富的神话而涌了进来,我也是如此。可我也相信我也有不同的地方,在真正能用这个语言、这个工具做些什么的时候,我的感觉就变了,变成了有很多的想法想要实现。曾经看过一个有关成功的演讲,主讲人总结的就是产品就是三步:WHY-HOW-WHAT。绝大多数的人最先想到的都是WHAT,比如做什么能赚钱,然后逆推回去,应该怎么做(HOW),然后就没有了。而成功的人呢,先想的都是为什么,为什么要做这个事情。答案基本上就是:我想让人类能像鸟一样飞起来,我想让人们都能简单的使用电脑,我想做一部最完美的手机。于是现在的我们坐上了莱特兄弟的飞机,用上了Windows系统的电脑,每天用iPhone打电话。我愿意相信我和这些人相同,我每天都有一个又一个的想法冒出来,我会把它们一个一个记录下来,最终用swift来实现出来,在编程这个行业里,语言只是HOW,是实现梦想的工具,工具运用的越好,我最终做出来的东西和我想象中的差距就越小,所以有了这样一个博客,我希望能把我学习swift中遇到的问题最终我解决的办法来分享出来,也许能收获更好的办法。

所以如果也有人来咨询我问是不是应该进入这个行业,我会先问他:“WHY”。不一定也要是心里的想法多得装不下需要有个地方来实现,也可以是:我很喜欢算法,我想我写的算法是最棒的被所有人知道!还可以是:我热爱编程,看到一行一行代码最终运行出了结果我很兴奋!这都可以,这些热爱和激情会为你带来不错的收入,这只不过是其中的附加价值,真正只想着“WHAT”这一步而最终赚到钱了可能性,大概就只有偷和抢了吧。所以也算对后来者一点建议,“我想有钱”,这个不能算是对“WHY”的答案。如果仅仅是来做一个coder,那其他行业一样可以挣钱,还很可能会更舒服。编程业苦,压力大,但对热爱的人来讲,这才是人生价值的所在。改编日漫经常用的一句话:这,才是programmer的浪漫啊。

在网站根目录显示安装在服务器子目录的WordPress网站

这个博客就是用WordPress建立的,我本身考虑过新浪或者CSDN的博客,但想了想,既然是一个技术类从业人员,自己建一个博客也不错吧。于是就买了某云的服务器,选择了WordPress这个建站工具,但是期间等待的主要时间都是备案审核。。真正建站真的花了不到5分钟,所以WordPress建站其实并不能算成很有成就的事情,遇到了一点困难,就是因为一开始就将WordPress安装到了子目录下,所以进来网站都是blog.swiftflamel.com/blog/,真心觉得很low,于是决定改变一下。WordPress官方推荐的方法是使用.htaccess伪静态方法来解决(实际也是这么解决的,但是可以用更简便的方法)

以下是简便版解决方法:

利用FTP链接到服务器,在安装了WordPress的路径下找到index.php和.htaccess文件,下载下来,打开index.php,找到

require( dirname( __FILE__ ) . ‘/wp-blog-header.php’ );

语句,将其更改为:

require( dirname( __FILE__ ) . ‘/blog/wp-blog-header.php’ );

其中‘blog’为安装WordPress的路径名

改好之后将两个文件上传到服务器的根目录(注意,这两个文件原来是在安装路径而不是根目录下)

重新打开网站网址,发现已经成功,WordPress会自动帮你修改.htaccess文件,当然,如果你希望自己修改.htaccess文件,下面提供官网的链接:

https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory

在该条条目下:

Pointing your home site’s URL to a subdirectory

Hello world!

一个共同学习swift语言并成长的地方,也许你好奇为什么一个编程技术博客会取这样一个名字,说实话,因为包括申请域名和备案过了太久,最开始为什么起了这个名字我都忘了,我只是不忘初心的把这个名字写了上去而已