轩辕十四

探索科技与创新的个人博客

最近做通知的时候需要对通知进行测试,之前没有做证书的经验,这次尝试了一下,写这篇文章备忘。

测试用的工具叫做 Pusher,下载地址:NWPusher。非常的好用。

创建测试用 Push 证书


1、打开苹果开发者页面:Developer,登录账户。

2、在账户的 Certificates, Identifiers & Profiles 页面找到 Identifiters,选择 App IDs

3、找到自己 App,点击打开,能看到如下所示。

如果你没有配置 Push Notifications,那么它的 DevelopmentDistribution 都是 Configurable 状态。点击 Edit 按钮。

我们要创建测试用的证书就点击 Development SSL Certificate 下面的 Create Certificate

阅读全文 »

Swift 是一门面向协议的编程语言,为什么这么说,请看 WWDC 视频 Protocol-Oriented Programming in Swift

通过闭包的方式为 UIControl 添加 action 的实现方式有很多种,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
extension UIControl {
func listen(_ action: @escaping () -> (), for controlEvents: UIControlEvents) -> AnyObject {
let sleeve = ClosureSleeve(attachTo: self, closure: action, controlEvents: controlEvents)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
return sleeve
}

func listenOnce(_ action: @escaping () -> (), for controlEvents: UIControlEvents) {
let sleeve = ClosureSleeve(attachTo: self, closure: action, controlEvents: controlEvents)
addTarget(sleeve, action: #selector(ClosureSleeve.invokeOnce), for: controlEvents)
}

func unlisten(sleeve: AnyObject) {
guard let sleeve = sleeve as? ClosureSleeve else { return }
self.removeTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: sleeve.controlEvents)
}
}

private class ClosureSleeve {
let closure: () -> ()
let controlEvents:UIControlEvents
let attachedTo: AnyObject

init(attachTo: AnyObject, closure: @escaping () -> (), controlEvents:UIControlEvents) {
self.attachedTo = attachTo
self.closure = closure
self.controlEvents = controlEvents
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
}

@objc func invoke() {
closure()
}

@objc func invokeOnce() {
closure()
attachedTo.unlisten(sleeve: self)
}
}
阅读全文 »

今天在项目中遇到了隐藏 navigationbar 功能的问题,例如:从 A push到 B 页面,A 页面的 navigationbar 是隐藏的,但是 B 页面的 navigationbar 是需要显示的。

一开始我在 A 页面调用 setNavigationBarHidden(true, animated: true) 方法,在 B 页面调用 setNavigationBarHidden(false, animated: true) 方法,虽然能够达到想要的效果,但是对于项目来说是灾难性的。因为如果有多个地方出现这种情况的话,你的代码将会变得十分的杂乱臃肿。

一种好的解决方式是调用 navigationcontroller 的代理:

1
navigationController(_:willShow:animated:)

将这个代理放在项目控制器的基类中,在这里我是放在我的基类 BaseViewController 中。为什么这么做?因为这样可以很好的去掉冗余的代码,不用写的到处都是,我的所有控制器都是继承自 BaseViewController 的,BaseViewController 继承自 UIViewController

下面到了 Show Code 的时候了

阅读全文 »

对 http 的抓包非常的简单,但是对 https 的抓包就有点麻烦了,主要麻烦在证书的安装与设置上。昨天由于有需要去抓https 的包,但是装好证书后,手机一直连不上,特此记录一下。

想要抓取 https 包,首先我们需要在电脑上安装一个 Charles Proxy 的证书

安装 Charles Root Certificate


1、依次点击:Help -> SSL Proxying -> Install Charles Root Certificate

阅读全文 »

尽管很多人了解 RxJava 的基本逻辑,但是在 Observable 链和操作符究竟运行在哪个线程,仍然会有许多困惑。

首先,让我们梳理清晰,在 RxJava 中 .subsribeOn().observeOn() 区别:

  1. .subsribeOn() 操作符可以改变 Observable 应该在哪个调度器上执行任务。
  2. .observeOn() 操作符可以改变 Observable 将在哪个调度器上发送通知。
  3. 另外,你需要知道,默认情况下,链上的操作符将会在调用 .subsribeOn() 的那个线程上执行任务。
阅读全文 »

好消息:Swift 4.2 现已在 Xcode 10 beta 中提供!此版本更新重要的 Swift 4.1 功能,并改进语言以准备 ABI 稳定性。

本教程介绍了 Swift 4.2 中最重要的变化。它需要 Xcode 10,因此请确保你在开始之前下载并安装 Xcode 的最新测试版。

前言


Swift 4.2 与 Swift 4.1 的源代码兼容,但与任何其他版本不兼容。 Apple 设计的 Swift 4.2 是在 Swift 5 中实现 ABI 稳定性的中间步骤,它应该能够在不同 Swift 版本编译的应用和库中保持二进制兼容。在集成到最终的 ABI 之前,ABI 功能会有大量的时间来获得来自社区的反馈。

本教程的部分包含 Swift Evolution 提案编号,如 [SE-0001] 。你可以通过点击每个提案的链接标签来浏览每个更改的详细信息。

阅读全文 »

今天需要去打印店打印东西,但是 U 盘被我格式化成了 APFS 格式,用磁盘管理工具无法格式化成其他的格式,选项中只有 APFS 的选项。我用如下的命令格式化 U 盘:

1
sudo diskutil eraseDisk JHFS+ san /dev/disk3

但是执行命令会报错,错误信息大致是,无法格式化 APFS 容器。

/dev/disk3 是我 U 盘的目录,在执行之前请先确认自己的目录,用如下的命令:

1
diskutil list 
阅读全文 »

理解引用计数


Objective-C 语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数器。如果想使某个对象继续存活,那就递增其引用计数;用完了之后,就递减其计数。计数变为 O,就表示没人关注此对象了,于是,就可以把它销毁。

引用计数工作原理

Objective-C 中,调用 alloc 方法所返回的对象由调用者所拥有。也就是说,调用者已通过 alloc 方法表达了想令该对象继续存活下去的意愿。不过请注意,这并不是说对象此时的保留计数必定是 1。在 alloc 或。initWithInt: 方法的实现代码中,也许还有其他对象也保留了此对象,所以,其保留计数可能会大于 1。能够肯定的是:保留计数至少为 1。保留计数这个概念就应该这样来理解才对。绝不应该说保留计数一定是某个值,只能说你所执行的操作是递增了该计数还是递减了该计数。

1
2
3
4
5
6
7
8
9
NSMutableArray *array = [[NSMutableArray alloc] init];
NSNumber *number = [[NSNumber alloc] initWithInt:1337];

[array addObject:number];
[number release];

// do something with 'array'

[array release];
阅读全文 »

在之前的一篇文章中【iOS 并发,锁,线程同步【一】GCD】,我们讨论了一下 GCD 的并发,锁和线程同步的问题,今天,我们来讨论一下 Operation 的并发与线程同步。

Operation 中,我们一般是将所有的 Operation 添加到 OperationQueue 中进行执行,这里需要注意一点,**Operation 添加到队列当中,默认就是执行的并发操作。我们可以设置队列的最大并发数 maxConcurrentOperationCount。如果我们在 OperationQueue 中想要执行串行任务的话,很简单,将 maxConcurrentOperationCount 设置成为1即可。 maxConcurrentOperationCount 的默认值为-1,那么默认情况下的并发数是多少呢?这个是由系统内存和 CPU 决定的,可能内存多久开多一点,内存少就开少一点。**最大并发数建议 2~3,如果并发数太多会导致 UI 卡顿。

不添加到队列当中的 Operation,我们可以调用 start() 方法开始一个操作,也可以调用 cancel() 取消等待中的操作,注意:已经开始执行的操作是没法取消的。代码示例如下:

1
2
3
4
5
let opt = BlockOperation {
print("Operation")
}
opt.start() // 开始执行任务
opt.cancel() // 取消等待中的任务
阅读全文 »

用 Objective-C 等面向对象语言编程时,“对象”(object)就是“基本构造单元”(building block),开发者可以通过对象来存储并传递数据。在对象之间传递数据并执行任务的过程就叫做“消息传递”(Messaging)。若想编写出高效且易维护的代码,就一定要熟悉这两个特性的工作原理。

当应用程序运行起来以后,为其提供相关支持的代码叫做“Objective-C 运行期环境”(Objective-C runtime),它提供了一些使得对象之间能够传递消息的重要函数,并且包含创建类实例所用的全部逻辑。在理解了运行期环境中各个部分协同工作的原理之后,你的开发水平将会进一步提升。

理解“属性”这一概念


“属性”(property)是 Objective-C 的一项特性,用于封装对象中的数据。Objective-C 对象通常会把其所需要的数据保存为各种实例变量。实例变量一般通过“存取方法”(access method)来访问,也就是 gettersetter 方法。

1
2
3
4
5
6
7
8
@interface EOCPerson: NSOjbect {
@public
NSString *_firstName;
NSString *_lastName;
@private
NSString *_someInternalData;
}
@end
阅读全文 »
0%