swift:为键盘添加自定义工具栏

有时候需要为键盘添加一些自定义的按键,如“上一步”,“下一眇”,“完成” 按钮等。

首先自定义一个toolbar

以及对应的响应方法

 

然后以UITextField初始化时加上

这样就可以为为键盘加上自定义行为了。

 

 

Swift学习: 从Objective-C到Swift

这篇文章是自己学习Swift的笔记与深化。希望这篇文章能够帮助已经有Objective-C经验的开发者更快地学习Swift。同时也品味到Swift的精妙之处。

文章组织脉络:

从Objective-C到Swift的语法差异。我们熟悉的Objective-C特性在Swift中如何展现。
从Objective-C到Swift的进步改进。研究对比Swift在安全性,易用性上的提升,给我们带来的新编程范式。

目录:

1.属性(property)和实例变量(instance variable)

2.控制流

3.函数

4.类与初始化(Initializers)

5.枚举与结构体

6.协议(Protocols)

7.Swift与Cocoa

8.总结

1.属性(property)和实例变量(instance variable)

Objective-C property in Swift world

在Cocoa世界开发的过程中,我们最常打交道的是property.

典型的声明为:

而在Swift当中,摆脱了C的包袱后,变得更为精炼,我们只需直接在类中声明即可。

注意到这里,我们不再需要@property指令,而在Objective-C中,我们可以指定property的attribute,例如strong、weak、readonly等。

而在Swift的世界中,我们通过其他方式来声明这些property的性质。

需要注意的几点:

strong: 在Swift中是默认的
weak: 通过weak关键词申明

readonly,readwrie 直接通过声明变量var,声明常量let的方式来指明
copy 通过@NSCopying指令声明。

值得注意的是String、Array和Dictionary在Swift是以值类型(value type)而不是引用类型(reference type)出现,因此它们在赋值、初始化、参数传递中都是以拷贝的方式进行(简单来说String,Array,Dictionary在Swift中是通过struct实现的)

延伸阅读:Value and Reference Types

nonatomic,atomic 所有的Swift properties都是nonatomic。但是我们在线程安全上已经有许多机制,例如NSLock、GCD相关API等。个人推测原因是苹果想把这一个本来就用的很少的特性去掉,线程安全方面交给平时我们用的更多的机制去处理。

然后值得注意的是,在Objective-C中,我们可以跨过property直接与instance variable打交道,而在Swift是不可以的。

例如:我们可以不需要将someString声明为property,直接使用即可。即使我们将otherString声明为property,我们也可以直接用_otherString来使用property背后的实例变量。

而在Swift中,我们不能直接与instance variable打交道。也就是我们声明的方式简化为简单的一种,简单来说在Swift中,我们只与property打交道。

A Swift property does not have a corresponding instance variable, and the backing store for a property is not accessed directly

小结

因此之前使用OC导致的像巧哥指出的开发争议就不再需要争执了,在Swift的世界里,我们只与property打交道。
并且我们在OC中init和dealloc不能使用属性self.property = XXX来进行设置的情况得以解决和统一。

(不知道这一条规定,在init直接用self.property = value 的同学请自觉阅读iOS夯实:内存管理)

:)

个人觉得这看似小小一点变动使Swift开发变得更加安全以及在代码的风格更为统一与稳定。

Swift property延伸:

Stored Properties和Computed properties

在Swift中,property被分为两类:Stored Properties和Computed …

dispatch_once 引起的死锁

今天遇到一个使用dispatch_once引起的问题,在shareInstance的dispatch_once里初始化的同时也调用了别的类的dispatch_once方法初始化,而在别的dispatch_once方法又调用本类的dispatch_once,莫名导致程序死锁。

在google后得知在初始化未完成时相互的调用会造成死锁,也就是A->B->C->A的一个调用过程,,会导致整体链表无限增长,造成永久性死锁。

为iOS添加3D touch功能

一、为ios添加3D Touch 的实现
1.在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中添加以下代码 :

2.实现这个方法-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler 在这个方法中处理添加和分享的事件,代码如下:

二、通过模拟器进行调试
使用SBShortcutMenuSimulator来配置模拟器,地址https://github.com/DeskConnect/SBShortcutMenuSimulator,使模拟器支持3D Touch,

在终端中按顺序输入以下命令:

然后打开刚才写好的程序 运行一下打开模拟器,再去终端中按顺序输入一下命令:

注意: ‘com.apple.mobilecal’ ”里边写的是自己项目的Bundle identifier. 
这行命令就是要让模拟器显示出3D Touch,每次想要显示快速入口只要重复
echo ‘com.apple.mobilecal’ | nc 127.0.0.1 8000
即可

我测试的时候crashed了,报了如下错误

google了下,发现我的模拟器ios版本是9.2,需要换成9.1,需要下载ios9.1的sdk包,打开模拟器Hardware->Devices->Manage Device
点击+按钮,选择Add Simulator。在iOS version 那一行选择ios9.1,如果没有9.1,就选择去下载一个9.1。

下载完成后,再次运行,成功显示定义的两个按钮

ios的静态load函数

ios在执行main()方法前,还做了很多工作,包括装载和一些初始化,比如熟知的+ load方法等,这样我们就很容易利用load方法对我们的程序进行一些初始化工作,而又不必多写其它的代码,或者引用其它的文件,降低了偶合度,只要在我们的class里加入+ load方法即可

这里有一篇文章分析得比较详细
iOS程序main函数之前发生了什么

升级xcode7开发问题汇总

1.The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.

Xcode7 编译程序无法连接网络,是因为Xcode7下,Apple要求数据传输协议必须支持Https协议(AST),否则将会默认无法连接网络。

目前网上已经给出临时解决办法:

2. fembed-bitcode is not supported on versions of iOS prior to 6.0

原因:Xcode7 及以上版本会默认开启 bitcode 。  

Xcode 7.0中, enable_bitcode选项是默认YES,导致所有的对象,静态库和用户框架中使用时必须包含bitcode,否则,编译发出错误。如果你使用了第三方提供的库或框架,需要更新包含bitcode的版本(包括第三方库)。

解决办法:

(1).更新library使包含Bitcode,否则会出现以上问题。
(2).关闭Bitcode,简单粗暴。

如果不想打开enable_bitcode,可以设置成NO。

 

3.Scheme白名单问题

-canOpenURL: failed for URL: “weixin://app/wxdaae92a9cfe5d54c/” – error: “This app is not allowed to query for scheme weixin”

 

近期苹果公司iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。
受此影响,当你的应用在iOS 9中需要使用微信SDK的相关能力(分享、收藏、支付、登录等)时,需要在“Info.plist”里增加如下代码:

<key>LSApplicationQueriesSchemes</key><array>
<string>mqqOpensdkSSoLogin</string>
<string>mqzone</string>
<string>sinaweibo</string>
<string>alipayauth</string>
<string>alipay</string>
<string>safepay</string>
<string>mqq</string>
<string>mqqapi</string>
<string>mqqopensdkapiV3</string>
<string>mqqopensdkapiV2</string>
<string>mqqapiwallet</string>
<string>mqqwpa</string>
<string>mqqbrowser</string>
<string>wtloginmqq2</string>
<string>weixin</string>
<string>wechat</string></array>

 

苹果审核踩过的坑

最近一段时间由于有三款应用需要申请appstore,三款应用加起来先后被拒绝了七八次,好在这些应用现在都通过了。其中包含了一些条款理解不浅析,也踩过一些坑,收集一下,为以后不会再踩上同一个坑。

1.包含竞赛与赌博
程序内有抽奖的,在评级处必须选上竞赛与赌博。
也必须在抽奖页面加上抽奖规则与说明。
在抽奖规则里必须声明苹果并不是这些抽奖与赌博的发起者和参与者。说白了就是声明这些活动都与苹果无关。

2.不能包含显示的版本信息和检查版本更新

3.提供测试账号
即使是只需要输入手机和手机验证码,也需要提供一个可登录的手机号的验证码,不然会登录不进去直接被拒。

3.包含注册登录
如果包含注册功能,必须包含有相应的用户信息系统(比如登录,个人中心之类的和用户注册的必须要性相关的功能),或者你在审核备注里添加说明为什么需要注册,不然会直接被拒,因为苹果怀疑你收集个人信息。

如果注册包含隐私信息(如手机号,性别等)也必须在注册页包含一个隐私条款的说明。

4.有黄色和侮辱性内容
比如图片内容涉及黄色内容,或者恶心等侮辱等内容。会被拒绝,比如我们有一张漫画看上去是竖中指,就被拒绝了

5.支付
苹果条款里说明购买虚拟产品或者内容,支付不能用第三方支付,只能使用苹果支付。但购买线下产品或者实际产品的,可以接入第三方支付(如微信,支付宝)。

App Store 审核条款

1.1
As a developer of Apps for the App Store you are bound by the terms of the Program License Agreement (PLA), Human Interface Guidelines (HIG), and any other licenses or contracts between you and Apple. The following rules and examples are intended to assist you in gaining acceptance for your App in the App Store, not to amend or remove provisions from any other agreement.

为App Store开发程序,开发者必须遵守 Program License Agreement (PLA)、人机交互指南(HIG)以及开发者和苹果签订的任何协议和合同。以下规则和示例旨在帮助开发者的程序能获得
2.1
Apps that crash will be rejected

崩溃的程序将会被拒绝。
2.2
Apps that exhibit bugs will …

代码签名探析

“用户会感激代码签名带来的好处” – Apple Developer Library: Code Signing Guide

在 iOS 或 OS X 平台上进行应用开发时,你所需要使用的 API 大多设计得简洁明了。你可以轻易地实现酷炫的动画效果,便捷地进行应用发布前测试,或是用 Core Data 将数据安全的存储在本地。但是总有一天,你会碰上代码签名 (code signing) 和配置文件 (provisioning),大多数情况下,这会是你在心里问候某些人祖宗的开始。

如果你已经在 iOS 上开发过应用,那么你多半已经与代码签名或设备配置文件打过交道了。即使是 OS X 开发者,如果你想发布自己的应用到 Mac App Store 上去或者想参与苹果的开发者项目,那么也不得不开始为自己的代码进行签名。

大多数时候代码签名看上去像是一个难以理解的神秘黑盒。在这篇文章里我会尽可能揭示盒子内部的运作机理。

通常来说,我们无法直接看到代码签名的运作过程,它们隐藏在 iOS 系统内部和 SDK 之中。但我们可以通过观察设置代码签名所需工具的运作方式,来找出一些线索。除此之外,我们还可以参考 OS X 上的代码签名运作方式,毕竟 iOS 和 OS X 系出同源,我们可以从他们的对比之中得到很多有用的信息。

OS X 上代码签名技术和相应的 API 是在 Mac OS X Leopard 10.5 上首次出现的,这刚好是第一台 iPhone 发布的时候。这并非巧合,因为在 iOS 上,代码签名起到的作用更加重要。iPhone 是在众多游戏主机之后第一个大规模出售并且从头就开始使用代码签名的计算平台。只有在越狱之后,iOS 才能运行没有签名的代码。越狱使应用可以绕过代码签名和沙盒安全机制的全部限制,这会是一个非常危险的行为。

证书和密匙
作为一个 iOS 开发者,在你开发使用的机器上应该已经有一个证书,一个公钥,以及一个私钥。这些是代码签名机制的核心。像 SSL 一样,代码签名也依赖于采用 X.509 标准的公开密钥加密。

在 OS X 上,X.509 的基本组成部分(译者注:例如证书等)都是由一个叫钥匙串访问的工具来进行管理。打开你开发机器上的钥匙串访问应用,选择类别选项下的“我的证书(My Certificates)”,你可以看到所有你持有的私钥相对应的证书。要用一个证书设置代码签名,你必须拥有私钥,所以所有你拥有私钥的证书都会被列在这里。如果你拥有一个证书的私钥,你可以展开证书并将它的私钥显示出来:

iOS Developer Certificate in the OS X keychain

如果你要导出证书,例如为了备份(强烈建议进行),一定要记得展开证书那一条显示出私钥并将两行都选中。

还有一种可以用来快速地显示出你的系统中能用来对代码进行签名的认证的方法,那就是利用用途广泛的命令行工具 security:

$ security find-identity …

iOS本地通知

为游戏添加了本地推送功能,写下来作为记录

本地通知相对于远程推送来说较简单。

IOS:

添加本地推送

/*
name:通知的唯一名字,可作为通知的id来用
message:通知的内容
time:触发通知的时候(倒计时时间)
*/
void SDKHelper::addLocalNotication(std::string name, std::string message,int time)
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
if (localNotification == nil) {
return;
}
//先把同名的系统通知取消(避免重复通知)
cancleLocalNotication(name);
//设置本地通知的触发时间(如果要立即触发,无需设置),如20秒后触发
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:time];
//通知的重复类型
localNotification.repeatInterval = NSCalendarUnitDay;
//设置本地通知的时区
localNotification.timeZone = [NSTimeZone defaultTimeZone];