swift实现持续震动

首先我必须说清楚的是,本文的重点不是讲如何通过Swift实现持续震动这个功能,而是通过实现这个功能来学习在Swift中如何把一个c函数作为另一个函数的参数。之所以选这个功能,也是百度了一下,发现并没有用swift实行的博客(要么语法过时,要么编译不过)。如果仅仅只是关注功能的实现,可以直接拉到底部。

如果你有OC使用经验,一定知道先要注册一个震动的回调:

let temp :UnsafeMutablePointer =nil

AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate,nil,nil,soundCompleteCallback(kSystemSoundID_Vibrate, temp),nil)

然后实现soundCompleteCallback这个回调函数:

 

上面这段代码的意思就是2秒震动一次,结下来当你使用

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)

我们预计的结果是回调到soundCompleteCallback函数,然后2秒后再次震动,然后又回调,2秒后再震动....这样就实现了持续震动。

然而,事实是Xcode会报一个异常:

Cannot convert value of type '()' to expected argument type 'AudioServicesSystemSoundCompletionProc' (aka '@convention(c) (UInt32, UnsafeMutablePointer<()>) -> ()')

大意就是参数不对,我们再看看swift源码

swift实现持续震动_第1张图片
AudioServicesAddSystemSoundCompletion
swift实现持续震动_第2张图片
AudioServicesSystemSoundCompletionProc

AudioServicesAddSystemSoundCompletion这个函数的第个4个参数是一个继承AudioServicesSystemSoundCompletionProc的c函数,看到这里我也是不得要领,欢迎大神在评论区指点。不过当我用oc那样只传函数名的时候,Xcode给了我一点提示:

A C function pointer can only be formed from a reference to a'func' or a literal closure

回调函数只能是一个指针指向一个C函数

在Swift中你只能通过一个全局函数或闭包(不能值捕获,如果你对swift中的闭包或者值捕获不了解,请参考:swift闭包(中文翻译)),不能使一个实例方法。于是我换成下面这种写法:

3行代码实现了持续震动

用闭包完美解决了这个“2秒一次,持续震动”的问题。但是,对于全局函数这种方式我也尝试了多次,发现始终解决不了。

水平有限,说错了的地方希望大神补充。

你可能感兴趣的:(swift实现持续震动)