iOS CoreTelephony框架介紹與使用案列

昨晚看一篇文章時看到了私有API這個詞,貌似開發者對私有API的使用很反感于是果斷百度谷歌,以下是Stackoverflow中關于Private Frameworks的一個解釋:

Private frameworks are frameworks which you are not allowed to use. They are not expected to be used outside of Apple, hence "Private". They are often lower-level libraries which may "break" the system if not used correctly. (But the frameworks have to exist because Apple's apps and public frameworks do use the private frameworks.)?

Since the private frameworks are not for public use, Apple doesn't need to give any headers or documentations away.

If you're writing for AppStore, you should not use private frameworks (unless you're from Apple). The system will immediately reject your app even before the review process begins.?

(On the other hand, for jailbroken platforms you're free to use any frameworks. Even so, the APIs of private frameworks is unstable, that you should avoid them if possible.?

There is an ongoing effort to document these private frameworks and API inhttp://iphonedevwiki.net/index.PHP/Main_Page.)


私有框架我們可以在SDK目錄中找到,詳細目錄如下:

[plain]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/PrivateFrameworks/??



一大堆,里面就提供了私有API,這些私有框架蘋果并不提倡我們使用,私有框架中沒有給出頭文件(好像可以導出)而且也沒有官方的文檔說明,一旦app中使用了私有API,那么審核將無法通過(但是據說Google的GoogleVoice使用了私有API并且通過了審核,背后發生了什么我們不得而知)。但是私有API的功能貌似非常強大,更加是越獄開發的必備工具。

于是我很好奇地想玩下私有API,搜到了一個CoreTelephony框架,貌似在iOS?6以前該框架是私有框架,但來到iOS 7之后該框架絕對是個公開的框架了,因為我在PrivateFrameworks目錄下找不到該框架,相反在上一層中的Frameworks目錄下找到了該框架:


Apple官網也給出了該框架的文檔:Core Telephony Framework Reference


無論如何,先試玩下這個框架。

參考網上的一篇文章(10年寫的,那個時候CoreTelephony框架應該還是個私有框架吧),簡單使用了一下該框架,用來輸出手機的運營商信息和簡單的通話信息。

首先要導入CoreTelephony框架:

[objc]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. //?首先導入CoreTelephony框架??
  2. @import?CoreTelephony;??

這里使用了@import關鍵字,所以要確保Enable Modules選項已經打開:



然后聲明一個CTCallCenter變量,該變量非strong屬性,所以不會導致在代碼塊中使用時形成retain cycle的問題:

[objc]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. @interface?ViewController?()?{??
  2. ????CTCallCenter?*center_;?//?為了避免形成retain?cycle而聲明的一個變量,指向接收通話中心對象??
  3. }??
  4. @end??

接著編寫獲取運營商信息的方法:

[objc]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. -?(void)getCarrierInfo?{??
  2. ????//?獲取運營商信息??
  3. ????CTTelephonyNetworkInfo?*info?=?[[CTTelephonyNetworkInfo?alloc]?init];??
  4. ????CTCarrier?*carrier?=?info.subscriberCellularProvider;??
  5. ????NSLog(@"carrier:%@",?[carrier?description]);??
  6. ??????
  7. ????//?如果運營商變化將更新運營商輸出??
  8. ????info.subscriberCellularProviderDidUpdateNotifier?=?^(CTCarrier?*carrier)?{??
  9. ????????NSLog(@"carrier:%@",?[carrier?description]);??
  10. ????};??
  11. ??????
  12. ????//?輸出手機的數據業務信息??
  13. ????NSLog(@"Radio?Access?Technology:%@",?info.currentRadioAccessTechnology);??
  14. }??

最后在viewDidLoad方法中注冊通話事件的處理代碼塊:

[objc]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. -?(void)viewDidLoad??
  2. {??
  3. ????[super?viewDidLoad];??
  4. ??????
  5. ????//?獲取并輸出手機的運營商信息??
  6. ????[self?getCarrierInfo];??
  7. ??????
  8. ????//?監控通話信息??
  9. ????CTCallCenter?*center?=?[[CTCallCenter?alloc]?init];??
  10. ????center_?=?center;??
  11. ????center.callEventHandler?=?^(CTCall?*call)?{??
  12. ????????NSSet?*curCalls?=?center_.currentCalls;??
  13. ????????NSLog(@"current?calls:%@",?curCalls);??
  14. ????????NSLog(@"call:%@",?[call?description]);??
  15. ????};??
  16. }??

這里有一點比較奇怪,如果我不使用CTCallCenter的currentCalls屬性,那么將無法輸出代碼塊中的參數call的信息。


代碼很簡單,功能也很有限,下面真機調試下(模擬器輸出為null,這個不用解釋了吧)。

啟動程序,控制臺輸出信息如下:

[plain]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. 2014-02-15?14:48:31.711?GetMyPhone[762:60b]?carrier:CTCarrier?(0x166682f0)?{??
  2. Carrier?name:?[中國移動]??
  3. Mobile?Country?Code:?[460]??
  4. Mobile?Network?Code:[07]??
  5. ISO?Country?Code:[cn]??
  6. Allows?VOIP??[YES]??
  7. }??
  8. 2014-02-15?14:48:31.713?GetMyPhone[762:60b]?Radio?Access?Technology:CTRadioAccessTechnologyEdge??

Radion Acess Technology的值包括:

[objc]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. /*?
  2. ?*?Radio?Access?Technology?values?
  3. ?*/??
  4. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyGPRS??????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  5. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyEdge??????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  6. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyWCDMA?????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  7. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyHSDPA?????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  8. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyHSUPA?????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  9. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyCDMA1x????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  10. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyCDMAEVDORev0??__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  11. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyCDMAEVDORevA??__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  12. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyCDMAEVDORevB??__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  13. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyeHRPD?????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??
  14. CORETELEPHONY_EXTERN?NSString?*?const?CTRadioAccessTechnologyLTE???????????__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);??

以上信息指的是手機的數據業務吧,我的是Edge,不知道是什么,搜了一下:

GPRS:(General Packet Radio Service),它是GSM移動電話用戶可用的一種移動數據業務, 是GSM的技術升級,屬于2.5G,簡單講就是網速更快了。?

EDGE:(Enhanced Data Rate for GSM Evolution),即增強型數據速率GSM演進技術。 是GPRS的技術升級,屬于2.75G。?

EDGE和GPRS同屬于從GSM到3G的過渡技術。


之后另外拿臺手機打入本機,并且Descline,輸出如下:

[plain]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. 2014-02-15?14:48:38.727?GetMyPhone[762:1803]?current?calls:{(??
  2. ????CTCall?(0x16620620)?{??
  3. callState:?[CTCallStateIncoming]??
  4. Call?ID:?[E3E1D27E-3644-4BE3-9748-5B835925EDC2]??
  5. }??
  6. ??
  7. )}??
  8. 2014-02-15?14:48:38.739?GetMyPhone[762:1803]?call:CTCall?(0x16620620)?{??
  9. callState:?[CTCallStateIncoming]??
  10. Call?ID:?[E3E1D27E-3644-4BE3-9748-5B835925EDC2]??
  11. }??
  12. 2014-02-15?14:48:42.684?GetMyPhone[762:1803]?current?calls:(null)??
  13. 2014-02-15?14:48:42.710?GetMyPhone[762:1803]?call:CTCall?(0x165267e0)?{??
  14. callState:?[CTCallStateDisconnected]??
  15. Call?ID:?[E3E1D27E-3644-4BE3-9748-5B835925EDC2]??
  16. }??

可以看到通話狀態由Incoming到Disconnected,在斷開通話時current calls變為nil了。


那么該app可不可以在后臺監控通話事件呢?答案是不行。

1.你可以讓手機進入后臺,然后用另外一臺手機打入本機,控制臺沒有關于通話信息的輸出。

2.你可以嘗試用本機打電話出去,此時我們調用了系統的Phone程序,Demo程序已經進入了后臺,無法監聽到任何通話信息。

3.用別的手機打入本機,選擇Answer(話費要錢,調試完不要忘記斷開通話啊),此時系統將調用Phone程序,Demo程序進入后臺,所以在控制臺輸出中我們找不到Disconnected的通知:

[plain]?view plaincopy
在CODE上查看代碼片派生到我的代碼片
  1. 2014-02-15?14:47:07.946?GetMyPhone[751:3407]?current?calls:{(??
  2. ????CTCall?(0x16642820)?{??
  3. callState:?[CTCallStateIncoming]??
  4. Call?ID:?[140AF363-434D-41EE-BDC9-4730F5865724]??
  5. }??
  6. ??
  7. )}??
  8. 2014-02-15?14:47:07.959?GetMyPhone[751:3407]?call:CTCall?(0x16642820)?{??
  9. callState:?[CTCallStateIncoming]??
  10. Call?ID:?[140AF363-434D-41EE-BDC9-4730F5865724]??
  11. }??
  12. 2014-02-15?14:47:15.836?GetMyPhone[751:1807]?current?calls:{(??
  13. ????CTCall?(0x16563140)?{??
  14. callState:?[CTCallStateConnected]??
  15. Call?ID:?[140AF363-434D-41EE-BDC9-4730F5865724]??
  16. }??
  17. ??
  18. )}??
  19. 2014-02-15?14:47:15.855?GetMyPhone[751:1807]?call:CTCall?(0x16563140)?{??
  20. callState:?[CTCallStateConnected]??
  21. Call?ID:?[140AF363-434D-41EE-BDC9-4730F5865724]??
  22. }??


本文簡單使用了一下CoreTelephony這個曾經的私有框架,等以后真正用上私有API時再寫文章做下筆記吧。

Demo已上傳:點此進入下載頁


參考資料:

Core Telephony

What are Private FrameWorks and how will we use them?

Block的Retain Cycle的解決方法

@import vs #import - iOS 7

private framework使用(該文章給出了私有框架的路徑)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/248039.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248039.shtml
英文地址,請注明出處:http://en.pswp.cn/news/248039.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JS數組的迭代器方法

迭代器forEachevery一、迭代器方法 迭代器方法, 這些方法對數組中的每一個元素應用一個函數,可以返回一個值,一組值或一個新數組。 不生成新數組的迭代器方法 1.forEach() forEach()輸出 forEach輸出結果2.every() 該方法按接受一個返回值為布…

Git 筆記

三個區域 下面三個區域,是Git虛擬的區域,看不到,摸不著。 工作區 工作區,指的是使用Git管理后的文件,這些文件顯示在磁盤上,供我們使用或修改的區域。所以,粗略的說,項目文件夾就是…

C# webapi 上傳下載圖片

客戶端上傳文件 string url url "webUploadFile";Uri server new Uri(url);HttpClient httpClient new HttpClient();MultipartFormDataContent multipartFormDataContent new MultipartFormDataContent();StreamContent streamConent new StreamContent(new F…

OC-@dynamic 關鍵字

dynamic這個關鍵詞,通常是用不到的。 它與synthesize的區別在于: 使用synthesize編譯器會確實的產生getter和setter方法,而dynamic僅僅是告訴編譯器這兩個方法在運行期會有的,無需產生警告。 假設有這么個場景,B類&…

git -- 練習的筆記

gitgitee.com:my_exercises/my_exercises.githttps://gitee.com/my_exercises/my_exercises/invite_link?invite3ab56c724a0aed34ae2bd193ce87e741e67fe05ee029cc01b7993663152babc57d76203fdafbbb42e766b0d826817bc91.在任意位置右鍵打開 2.初始化設置 3.添加遠程倉庫地址 4.…

Swift傻傻分不清楚系列(十二) 屬性

本頁包含內容: 存儲屬性(Stored Properties)計算屬性(Computed Properties)屬性觀察器(Property Observers)全局變量和局部變量(Global and Local Variables)類型屬性&a…

GIT — 使用回顧

回顧Git的使用 記錄每次的變更 工作區 --> 暫存區 git add . / git add 文件 文件夾 .... 工作區 --> 暫存區/本地倉庫 前提條件:文件曾經被添加到暫存區或提交到倉庫git commit -a -m 提交說明 暫存區 --> 本地倉庫 git commit -m 提交說明 / git commi…

獲取兩個數百分比的值

1 /**2 * 獲取兩個數百分比的值3 * 4 * param num1 5 * param num26 * param retain 保留小數位數7 * return8 */9 public static String numberFormat(int num1, int num2, int retain) { 10 NumberFormat numberFormat …

iOS AVAudioPlayer和AVAudioPlayerDelegate-音頻播放處理中斷

學習總是在進行。 一、AVAudioPlayer如何處理中斷 AVAudioPlayer類提供了代理方法&#xff0c;用來處理當播放音頻文件時&#xff0c;發生來電、鬧鐘等事件。設置代理并遵守AVAudioPlayerDelegate協議,<span style"font-family: Arial, Helvetica, sans-serif;"&g…

Ajax — 大事件項目(第一天)

應用的前端技術 Ajax (重要) — jQuery方式接口請求Layui 框架使用HTML CSS JS 項目說明和演示 線上 DEMO 項目地址&#xff1a;http://www.liulongbin.top:8086/項目的 API 接口地址&#xff1a; https://www.showdoc.cc/escook?page_id3707158761215217 項目請求根路徑…

JS,JQ 格式化小數位數

在<script>中&#xff1a; $(function(){   var num$(".price").length;/*獲取應用了class"price"的標簽數量*/   for(var i0;i<num;i){     if($(".price")[i].innerText!"")       $(".price")[i]…

iOS開發實用技巧—Objective-C中的各種遍歷(迭代)方式

說明&#xff1a; 1&#xff09;該文簡短介紹在iOS開發中遍歷字典、數組和集合的幾種常見方式。 2&#xff09;該文對應的代碼可以在下面的地址獲得&#xff1a;https://github.com/HanGangAndHanMeimei/Code 一、使用for循環 要遍歷字典、數組或者是集合&#xff0c;for循環是…

windows系統作為客戶端時,linux中本地yum源掛載時,如何同時掛載DVD1和DVD2?

這里以CentOS6.5為例.他的鏡像有兩個DVD1和DVD2.DVD1中是系統和主要的安裝包,DVD2中是剩下的安裝包 當掛載時如果要同時掛載DVD1和DVD2.需要這樣做: 1)在虛擬機的設置中選擇連接 2)分別在mnt下創建cdrom和cdrom1文件夾 3)到dev下查看有軟連接 cdrom->sr0 cdrom1->sr1 這里…

Ajax — 大事件項目(第二天)

大事件-02 fix一個bug 原因&#xff1a; 開始做注冊的時候&#xff0c;頁面中只有一個 namepassword的input&#xff0c;所以 $(‘input[name“password”]’) 可以準確的找到元素后來做登錄的時候&#xff0c;頁面中多了一個namepassword的input&#xff0c;所以$(‘input[…

OpenCV自帶dnn的Example研究(3)— object_detection

這個博客系列&#xff0c;簡單來說&#xff0c;今天我們就是要研究https://docs.opencv.org/master/examples.html下的6個文件&#xff0c;看看在最新的OpenCV中&#xff0c;它們是如何發揮作用的。在配置使用的過程中&#xff0c;需要注意使用較高版本的VS避免編譯器兼容問題&…

Ajax — 大事件項目(第三天)

大事件-03 用戶信息 表單驗證 html中&#xff0c;直接使用layui提供的內置驗證規則 email <input type"text" name"email" required lay-verify"required|email" placeholder"請輸入郵箱" autocomplete"off" class&q…

iOS中監測來電方案

問題 最近在做一個有錄音功能的App&#xff0c;要求當用戶接到來電時&#xff0c;要停止錄音。該如何實現這個功能呢&#xff1f; 解決方案 我首先想到了AppDelegate里的applicationWillResignActive:方法&#xff0c;在該方法的注釋中就寫到到收到來電或短信時&#xff0c;系統…

iOS運行時-使用Runtime向Category中添加屬性以及運行時介紹

前言 了解OC的都應該知道&#xff0c;在一般情況下&#xff0c;我們是不能向Category中添加屬性的&#xff0c;只能添加方法&#xff0c;但有些情況向&#xff0c;我們確實需要向Category中添加屬性&#xff0c;而且很多系統的API也有一些在Category添加屬性的情況&#xff0c;…

Ajax — cropper (圖片剪裁)基本用法

jQuery-cropper插件完整的API&#xff1a;http://www.jq22.com/jquery-info9322 1. 基本使用步驟 在 <head> 中導入 cropper.css 樣式表&#xff1a; <link rel"stylesheet" href"/assets/lib/cropper/cropper.css" />在 <body> 的結…

「短篇小說」靈囚 540 天

轉載&#xff1a;知乎 - BIMBOX 孫彬 - https://zhuanlan.zhihu.com/p/24655832 「我們總有一天會逾越那條上帝劃好的界限&#xff0c;而最終我們將無法面對真實和虛假&#xff0c;正義與罪惡。」 「不幸的是&#xff0c;從伊甸園那一次&#xff0c;我們就已經越界了。」 第十天…