A new easy way to Screenshot&Share

Put a website in your Favorites or Bookmark? Now you can put it in your photos!

  • Support both website and markdown files

    Easy share present your extremely easy way to get a screenshot from a website or even markdown files. Open the website or markdown file and click the button and you will get your screenshot

  • Full size screenshot

    The screenshot you take will be full size of the website you opened, so you can share with your friends on social apps, or if you want, save to your photos so the next time you want to review the website you won’t have to open your safari and search the bookmark.

  • Efficient ways to open a URL

    We present many easy ways for you to open a URL. You can scan a QR code with a URL. Or you can input the address manually. What’s more, if you copy a URL from safari or some other apps, you don’t have to paste it, our app will recognize it automatically and auto paste it for you.

  • Efficient markdown editor

    We also present a efficient markdown keyboard for users who want to write a markdown article. And of course several markdown themes you can switch easily

 

  • The url you copy should be start with ‘http://’ or ‘https://’

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