那些著名和非著名的 iOS 面試 - 中篇

作為一個(gè)開(kāi)發(fā)者,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要,這是一個(gè)我的iOS交流群:638302184,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經(jīng)驗(yàn),討論技術(shù), 大家一起交流學(xué)習(xí)成長(zhǎng)!

群內(nèi)提供數(shù)據(jù)結(jié)構(gòu)與算法、底層進(jìn)階、swift、逆向、整合面試題等免費(fèi)資料
附上一份收集的各大廠面試題(附答案) ! 群文件直接獲取
各大廠面試題

推薦閱讀:iOS開(kāi)發(fā)——BAT面試題合集(持續(xù)更新中)

Swift好多坑,一個(gè)人填不來(lái),怎么辦

問(wèn)身邊同事吧,又怕被暗笑技術(shù)差勁

1、反轉(zhuǎn)二叉樹(shù),不用遞歸

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

遞歸方式:

public class Solution {
public TreeNode invertTree(TreeNode root) {
    if (root == null) {
        return null;
    }
    root.left = invertTree(root.left);
    root.right = invertTree(root.right);
    TreeNode tmp = root.left;
    root.left = root.right;
    root.right = tmp;
    return root;
}
}

object-c實(shí)現(xiàn):

[Objective-C] 純文本查看 復(fù)制代碼

/** 
 * 翻轉(zhuǎn)二叉樹(shù)(又叫:二叉樹(shù)的鏡像) 
 *
 * @param rootNode 根節(jié)點(diǎn)
 *
 * @return 翻轉(zhuǎn)后的樹(shù)根節(jié)點(diǎn)(其實(shí)就是原二叉樹(shù)的根節(jié)點(diǎn)) 
 */
 + (BinaryTreeNode *)invertBinaryTree:(BinaryTreeNode *)rootNode {
    if (!rootNode) {  return nil; } 
    if (!rootNode.leftNode && !rootNode.rightNode) {  return rootNode; } 
    [self invertBinaryTree:rootNode.leftNode];
    [self invertBinaryTree:rootNode.rightNode]; 
    BinaryTreeNode *tempNode = rootNode.leftNode; 
    rootNode.leftNode = rootNode.rightNode;
    rootNode.rightNode = tempNode; 
    return rootNode;
  }

非遞歸方式:

[Objective-C] 純文本查看 復(fù)制代碼

+ (BinaryTreeNode *)invertBinaryTree:(BinaryTreeNode *)rootNode {
if (!rootNode) {  return nil; }
if (!rootNode.leftNode && !rootNode.rightNode) {  return rootNode; }
NSMutableArray *queueArray = [NSMutableArray array]; //數(shù)組當(dāng)成隊(duì)列
[queueArray addObject:rootNode]; //壓入根節(jié)點(diǎn)
while (queueArray.count > 0) {
    BinaryTreeNode *node = [queueArray firstObject];
    [queueArray removeObjectAtIndex:0]; //彈出最前面的節(jié)點(diǎn),仿照隊(duì)列先進(jìn)先出原則
    BinaryTreeNode *pLeft = node.leftNode;
    node.leftNode = node.rightNode;
    node.rightNode = pLeft;

    if (node.leftNode) {
        [queueArray addObject:node.leftNode];
    }
    if (node.rightNode) {
        [queueArray addObject:node.rightNode];
    }

}

return rootNode;
}

示例代碼參考:二叉樹(shù)

2、寫(xiě)一個(gè)單例模式

[Objective-C] 純文本查看 復(fù)制代碼

+ (AccountManager *)sharedManager
{
    static AccountManager *sharedAccountManagerInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
            sharedAccountManagerInstance = [[self alloc] init]; 
    });
return sharedAccountManagerInstance;
}

3、iOS應(yīng)用生命周期

應(yīng)用程序的狀態(tài):

  • Not running未運(yùn)行:程序沒(méi)啟動(dòng)。
  • Inactive未激活:程序在前臺(tái)運(yùn)行,不過(guò)沒(méi)有接收到事件。在沒(méi)有事件處理情況下程序通常停留在這個(gè)狀態(tài)。
  • Active激活:程序在前臺(tái)運(yùn)行而且接收到了事件。這也是前臺(tái)的一個(gè)正常的模式。
  • Backgroud后臺(tái):程序在后臺(tái)而且能執(zhí)行代碼,大多數(shù)程序進(jìn)入這個(gè)狀態(tài)后會(huì)在在這個(gè)狀態(tài)上停留一會(huì)。時(shí)間到之后會(huì)進(jìn)入掛起狀態(tài)(Suspended)。有的程序經(jīng)過(guò)特殊的請(qǐng)求后可以長(zhǎng)期處于Backgroud狀態(tài)。
  • Suspended掛起:程序在后臺(tái)不能執(zhí)行代碼。系統(tǒng)會(huì)自動(dòng)把程序變成這個(gè)狀態(tài)而且不會(huì)發(fā)出通知。當(dāng)掛起時(shí),程序還是停留在內(nèi)存中的,當(dāng)系統(tǒng)內(nèi)存低時(shí),系統(tǒng)就把掛起的程序清除掉,為前臺(tái)程序提供更多的內(nèi)存。

iOS的入口在main.m文件:

int main(int argc, char *argv[])
{
@autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

main函數(shù)的兩個(gè)參數(shù),iOS中沒(méi)有用到,包括這兩個(gè)參數(shù)是為了與標(biāo)準(zhǔn)ANSI C保持一致。 UIApplicationMain函數(shù),前兩個(gè)和main函數(shù)一樣,重點(diǎn)是后兩個(gè)。

后兩個(gè)參數(shù)分別表示程序的主要類(lèi)(principal class)和代理類(lèi)(delegate class)。如果主要類(lèi)(principal class)為nil,將從Info.plist中獲取,如果Info.plist中不存在對(duì)應(yīng)的key,則默認(rèn)為UIApplication;如果代理類(lèi)(delegate class)將在新建工程時(shí)創(chuàng)建。

根據(jù)UIApplicationMain函數(shù),程序?qū)⑦M(jìn)入AppDelegate.m,這個(gè)文件是xcode新建工程時(shí)自動(dòng)生成的。下面看一下AppDelegate.m文件,這個(gè)關(guān)乎著應(yīng)用程序的生命周期。

1、application didFinishLaunchingWithOptions:當(dāng)應(yīng)用程序啟動(dòng)時(shí)執(zhí)行,應(yīng)用程序啟動(dòng)入口,只在應(yīng)用程序啟動(dòng)時(shí)執(zhí)行一次。若用戶直接啟動(dòng),lauchOptions內(nèi)無(wú)數(shù)據(jù),若通過(guò)其他方式啟動(dòng)應(yīng)用,lauchOptions包含對(duì)應(yīng)方式的內(nèi)容。

2、applicationWillResignActive:在應(yīng)用程序?qū)⒁苫顒?dòng)狀態(tài)切換到非活動(dòng)狀態(tài)時(shí)候,要執(zhí)行的委托調(diào)用,如 按下 home 按鈕,返回主屏幕,或全屏之間切換應(yīng)用程序等。

3、applicationDidEnterBackground:在應(yīng)用程序已進(jìn)入后臺(tái)程序時(shí),要執(zhí)行的委托調(diào)用。

4、applicationWillEnterForeground:在應(yīng)用程序?qū)⒁M(jìn)入前臺(tái)時(shí)(被激活),要執(zhí)行的委托調(diào)用,剛好與applicationWillResignActive 方法相對(duì)應(yīng)。

5、applicationDidBecomeActive:在應(yīng)用程序已被激活后,要執(zhí)行的委托調(diào)用,剛好與applicationDidEnterBackground 方法相對(duì)應(yīng)。

6、applicationWillTerminate:在應(yīng)用程序要完全推出的時(shí)候,要執(zhí)行的委托調(diào)用,這個(gè)需要要設(shè)置UIApplicationExitsOnSuspend的鍵值。

初次啟動(dòng):

iOS_didFinishLaunchingWithOptions

iOS_applicationDidBecomeActive

按下home鍵:

iOS_applicationWillResignActive

iOS_applicationDidEnterBackground

點(diǎn)擊程序圖標(biāo)進(jìn)入:

iOS_applicationWillEnterForeground

iOS_applicationDidBecomeActive

當(dāng)應(yīng)用程序進(jìn)入后臺(tái)時(shí),應(yīng)該保存用戶數(shù)據(jù)或狀態(tài)信息,所有沒(méi)寫(xiě)到磁盤(pán)的文件或信息,在進(jìn)入后臺(tái)時(shí),最后都寫(xiě)到磁盤(pán)去,因?yàn)槌绦蚩赡茉诤笈_(tái)被殺死。釋放盡可能釋放的內(nèi)存。

[Objective-C] 純文本查看 復(fù)制代碼

- (void)applicationDidEnterBackground:(UIApplication *)application

方法有大概5秒的時(shí)間讓你完成這些任務(wù)。如果超過(guò)時(shí)間還有未完成的任務(wù),你的程序就會(huì)被終止而且從內(nèi)存中清除。

如果還需要長(zhǎng)時(shí)間的運(yùn)行任務(wù),可以在該方法中調(diào)用

[Objective-C] 純文本查看 復(fù)制代碼

[application beginBackgroundTaskWithExpirationHandler:^{ 

    NSLog(@"begin Background Task With Expiration Handler"); 

}];

程序終止

程序只要符合以下情況之一,只要進(jìn)入后臺(tái)或掛起狀態(tài)就會(huì)終止:

①iOS4.0以前的系統(tǒng)

②app是基于iOS4.0之前系統(tǒng)開(kāi)發(fā)的。

③設(shè)備不支持多任務(wù)

④在Info.plist文件中,程序包含了 UIApplicationExitsOnSuspend 鍵。

系統(tǒng)常常是為其他app啟動(dòng)時(shí)由于內(nèi)存不足而回收內(nèi)存最后需要終止應(yīng)用程序,但有時(shí)也會(huì)是由于app很長(zhǎng)時(shí)間才響應(yīng)而終止。如果app當(dāng)時(shí)運(yùn)行在后臺(tái)并且沒(méi)有暫停,系統(tǒng)會(huì)在應(yīng)用程序終止之前調(diào)用app的代理的方法 - (void)applicationWillTerminate:(UIApplication *)application,這樣可以讓你可以做一些清理工作。你可以保存一些數(shù)據(jù)或app的狀態(tài)。這個(gè)方法也有5秒鐘的限制。超時(shí)后方法會(huì)返回程序從內(nèi)存中清除。

注意:用戶可以手工關(guān)閉應(yīng)用程序。

4、一工人給老板打7天工要求一塊金條 這金條只能切2次 工人每天要1/7金條 怎么分?

這道題解決的主要難點(diǎn)在于:不是給出去的就收不回來(lái)了,可以用交換的方法。

把金條分成三段(就是分兩次,或者切兩刀),分別是整根金條的1/7、2/7、 4/7。

第一天:給1/7的, 第二天:給2/7的,收回1/7的; 第三天,給1/7的; 第四天:給4/7的,收回1/7和2/7的 ;第五天:給1/7的 ;第六天:給2/7的,收回1/7的;第七天發(fā)1/7。

5、iOS中socket使用

Socket是對(duì)TCP/IP協(xié)議的封裝,Socket本身并不是協(xié)議,而是一個(gè)調(diào)用接口(API),通過(guò)Socket,我們才能使用TCP/IP協(xié)議。

http協(xié)議 對(duì)應(yīng)于應(yīng)用層

tcp協(xié)議 對(duì)應(yīng)于傳輸層

ip協(xié)議 對(duì)應(yīng)于網(wǎng)絡(luò)層

三者本質(zhì)上沒(méi)有可比性。 何況HTTP協(xié)議是基于TCP連接的。

TCP/IP是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸;而HTTP是應(yīng)用層協(xié)議,主要解決如何包裝數(shù)據(jù)。

我 們?cè)趥鬏敂?shù)據(jù)時(shí),可以只使用傳輸層(TCP/IP),但是那樣的話,由于沒(méi)有應(yīng)用層,便無(wú)法識(shí)別數(shù)據(jù)內(nèi)容,如果想要使傳輸?shù)臄?shù)據(jù)有意義,則必須使用應(yīng)用層 協(xié)議,應(yīng)用層協(xié)議很多,有HTTP、FTP、TELNET等等,也可以自己定義應(yīng)用層協(xié)議。WEB使用HTTP作傳輸層協(xié)議,以封裝HTTP文本信息,然 后使用TCP/IP做傳輸層協(xié)議將它發(fā)送到網(wǎng)絡(luò)上。

SOCKET原理

1、套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元。它是網(wǎng)絡(luò)通信過(guò)程中端點(diǎn)的抽象表示,包含進(jìn)行網(wǎng)絡(luò)通信必須的五種信息:連接使用的協(xié)議,本地主機(jī)的IP地址,本地進(jìn)程的協(xié)議端口,遠(yuǎn)地主機(jī)的IP地址,遠(yuǎn)地進(jìn)程的協(xié)議端口。

應(yīng) 用層通過(guò)傳輸層進(jìn)行數(shù)據(jù)通信時(shí),TCP會(huì)遇到同時(shí)為多個(gè)應(yīng)用程序進(jìn)程提供并發(fā)服務(wù)的問(wèn)題。多個(gè)TCP連接或多個(gè)應(yīng)用程序進(jìn)程可能需要通過(guò)同一個(gè) TCP協(xié)議端口傳輸數(shù)據(jù)。為了區(qū)別不同的應(yīng)用程序進(jìn)程和連接,許多計(jì)算機(jī)操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口。應(yīng) 用層可以和傳輸層通過(guò)Socket接口,區(qū)分來(lái)自不同應(yīng)用程序進(jìn)程或網(wǎng)絡(luò)連接的通信,實(shí)現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。

2 、建立socket連接

建立Socket連接至少需要一對(duì)套接字,其中一個(gè)運(yùn)行于客戶端,稱(chēng)為ClientSocket,另一個(gè)運(yùn)行于服務(wù)器端,稱(chēng)為ServerSocket。

套接字之間的連接過(guò)程分為三個(gè)步驟:服務(wù)器監(jiān)聽(tīng),客戶端請(qǐng)求,連接確認(rèn)。

服務(wù)器監(jiān)聽(tīng):服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài),等待客戶端的連接請(qǐng)求。

客戶端請(qǐng)求:指客戶端的套接字提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號(hào),然后就向服務(wù)器端套接字提出連接請(qǐng)求。

連 接確認(rèn):當(dāng)服務(wù)器端套接字監(jiān)聽(tīng)到或者說(shuō)接收到客戶端套接字的連接請(qǐng)求時(shí),就響應(yīng)客戶端套接字的請(qǐng)求,建立一個(gè)新的線程,把服務(wù)器端套接字的描述發(fā)給客戶 端,一旦客戶端確認(rèn)了此描述,雙方就正式建立連接。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽(tīng)狀態(tài),繼續(xù)接收其他客戶端套接字的連接請(qǐng)求。

3、SOCKET連接與TCP連接

創(chuàng)建Socket連接時(shí),可以指定使用的傳輸層協(xié)議,Socket可以支持不同的傳輸層協(xié)議(TCP或UDP),當(dāng)使用TCP協(xié)議進(jìn)行連接時(shí),該Socket連接就是一個(gè)TCP連接。

4、Socket連接與HTTP連接

由 于通常情況下Socket連接就是TCP連接,因此Socket連接一旦建立,通信雙方即可開(kāi)始相互發(fā)送數(shù)據(jù)內(nèi)容,直到雙方連接斷開(kāi)。但在實(shí)際網(wǎng)絡(luò)應(yīng)用 中,客戶端到服務(wù)器之間的通信往往需要穿越多個(gè)中間節(jié)點(diǎn),例如路由器、網(wǎng)關(guān)、防火墻等,大部分防火墻默認(rèn)會(huì)關(guān)閉長(zhǎng)時(shí)間處于非活躍狀態(tài)的連接而導(dǎo)致 Socket 連接斷連,因此需要通過(guò)輪詢(xún)告訴網(wǎng)絡(luò),該連接處于活躍狀態(tài)。

而HTTP連接使用的是“請(qǐng)求—響應(yīng)”的方式,不僅在請(qǐng)求時(shí)需要先建立連接,而且需要客戶端向服務(wù)器發(fā)出請(qǐng)求后,服務(wù)器端才能回復(fù)數(shù)據(jù)。

很 多情況下,需要服務(wù)器端主動(dòng)向客戶端推送數(shù)據(jù),保持客戶端與服務(wù)器數(shù)據(jù)的實(shí)時(shí)與同步。此時(shí)若雙方建立的是Socket連接,服務(wù)器就可以直接將數(shù)據(jù)傳送給 客戶端;若雙方建立的是HTTP連接,則服務(wù)器需要等到客戶端發(fā)送一次請(qǐng)求后才能將數(shù)據(jù)傳回給客戶端,因此,客戶端定時(shí)向服務(wù)器端發(fā)送連接請(qǐng)求,不僅可以 保持在線,同時(shí)也是在“詢(xún)問(wèn)”服務(wù)器是否有新的數(shù)據(jù),如果有就將數(shù)據(jù)傳給客戶端。

下面這篇文章是AsyncSocket的使用教程,大家可以看看。

6、網(wǎng)絡(luò)請(qǐng)求中post和get的區(qū)別

GET是用于獲取數(shù)據(jù)的,POST一般用于將數(shù)據(jù)發(fā)給服務(wù)器之用。

普遍答案

1.GET使用URL或Cookie傳參。而POST將數(shù)據(jù)放在BODY中。

2.GET的URL會(huì)有長(zhǎng)度上的限制,則POST的數(shù)據(jù)則可以非常大。

3.POST比GET安全,因?yàn)閿?shù)據(jù)在地址欄上不可見(jiàn)。

不過(guò)也有文章說(shuō)其實(shí)上面的是錯(cuò)誤的,具體參考這篇文章

7、時(shí)間復(fù)雜度和空間復(fù)雜度

由于打不出數(shù)字符號(hào),只能貼圖了。

<ignore_js_op>[圖片上傳中...(image-4ebe50-1554465783411-6)]</ignore_js_op>

時(shí)間復(fù)雜度

求時(shí)間復(fù)雜度

【1】如果算法的執(zhí)行時(shí)間不隨著問(wèn)題規(guī)模n的增加而增長(zhǎng),即使算法中有上千條語(yǔ)句,其執(zhí)行時(shí)間也不過(guò)是一個(gè)較大的常數(shù)。此類(lèi)算法的時(shí)間復(fù)雜度是O(1)。

x=91; y=100;while(y>0) if(x>100) {x=x-10;y--;} else x++;解答: T(n)=O(1)

這段程序的運(yùn)行是和n無(wú)關(guān)的,就算它再循環(huán)一萬(wàn)年,我們也不管他,只是一個(gè)常數(shù)階的函數(shù)。

【2】當(dāng)有若干個(gè)循環(huán)語(yǔ)句時(shí),算法的時(shí)間復(fù)雜度是由嵌套層數(shù)最多的循環(huán)語(yǔ)句中最內(nèi)層語(yǔ)句的頻度f(wàn)(n)決定的。

 x=1; 
for(i=1;i<=n;i++) 
    for(j=1;j<=i;j++)
       for(k=1;k<=j;k++)
           x++;

該程序段中頻度最大的語(yǔ)句是(5),內(nèi)循環(huán)的執(zhí)行次數(shù)雖然與問(wèn)題規(guī)模n沒(méi)有直接關(guān)系,但是卻與外層循環(huán)的變量取值有關(guān),而最外層循環(huán)的次數(shù)直接與n有關(guān),因此可以從內(nèi)層循環(huán)向外層分析語(yǔ)句(5)的執(zhí)行次數(shù): 則該程序段的時(shí)間復(fù)雜度為

<ignore_js_op>[圖片上傳中...(image-e2e9d6-1554465783411-5)]</ignore_js_op>

【3】算法的時(shí)間復(fù)雜度不僅僅依賴(lài)于問(wèn)題的規(guī)模,還與輸入實(shí)例的初始狀態(tài)有關(guān)。

在數(shù)值A(chǔ)[0..n-1]中查找給定值K的算法大致如下:

i=n-1;            
while(i>=0&&(A[ i ]!=k))       
  i--;        
return i;

此算法中的語(yǔ)句(3)的頻度不僅與問(wèn)題規(guī)模n有關(guān),還與輸入實(shí)例中A的各元素取值及K的取值有關(guān): ①若A中沒(méi)有與K相等的元素,則語(yǔ)句(3)的頻度f(wàn)(n)=n; ②若A的最后一個(gè)元素等于K,則語(yǔ)句(3)的頻度f(wàn)(n)是常數(shù)0。

空間復(fù)雜度

一個(gè)程序的空間復(fù)雜度是指運(yùn)行完一個(gè)程序所需內(nèi)存的大小。利用程序的空間復(fù)雜度,可以對(duì)程序的運(yùn)行所需要的內(nèi)存多少有個(gè)預(yù)先估計(jì)。一個(gè)程序執(zhí)行時(shí)除了需要存儲(chǔ)空間和存儲(chǔ)本身所使用的指令、常數(shù)、變量和輸入數(shù)據(jù)外,還需要一些對(duì)數(shù)據(jù)進(jìn)行操作的工作單元和存儲(chǔ)一些為現(xiàn)實(shí)計(jì)算所需信息的輔助空間。程序執(zhí)行時(shí)所需存儲(chǔ)空間包括以下兩部分。

(1)固定部分。這部分空間的大小與輸入/輸出的數(shù)據(jù)的個(gè)數(shù)多少、數(shù)值無(wú)關(guān)。主要包括指令空間(即代碼空間)、數(shù)據(jù)空間(常量、簡(jiǎn)單變量)等所占的空間。這部分屬于靜態(tài)空間。

(2)可變空間,這部分空間的主要包括動(dòng)態(tài)分配的空間,以及遞歸棧所需的空間等。這部分的空間大小與算法有關(guān)。

一個(gè)算法所需的存儲(chǔ)空間用f(n)表示。S(n)=O(f(n))  其中n為問(wèn)題的規(guī)模,S(n)表示空間復(fù)雜度。

8、支付寶SDK使用

使用支付寶進(jìn)行一個(gè)完整的支付功能,大致有以下步驟:向支付寶申請(qǐng), 與支付寶簽約,獲得商戶ID(partner)和賬號(hào)ID(seller)和私鑰(privateKey)。下載支付寶SDK,生成訂單信息,簽名加密調(diào)用支付寶客戶端,由支付寶客戶端跟支付寶安全服務(wù)器打交道。支付完畢后,支付寶客戶端會(huì)自動(dòng)跳回到原來(lái)的應(yīng)用程序,在原來(lái)的應(yīng)用程序中顯示支付結(jié)果給用戶看。

集成之后可能遇到的問(wèn)題

1)集成SDK編譯時(shí)找不到 openssl/asn1.h 文件

<ignore_js_op>[圖片上傳中...(image-ab2d3f-1554465783411-4)]</ignore_js_op>

解決方案:Build Settings --> Search Paths --> Header Search paths : $(SRCROOT)/支付寶集成/Classes/Alipay

<ignore_js_op>[圖片上傳中...(image-f3af44-1554465783411-3)]</ignore_js_op>

2)鏈接時(shí):找不到 SystemConfiguration.framework 這個(gè)庫(kù)

<ignore_js_op>[圖片上傳中...(image-e127d5-1554465783411-2)]</ignore_js_op>

解決方案:

<ignore_js_op>[圖片上傳中...(image-e2d86-1554465783411-1)]</ignore_js_op>

打開(kāi)支付寶客戶端進(jìn)行支付(用戶沒(méi)有安裝支付寶客戶端,直接在應(yīng)用程序中添加一個(gè)WebView,通過(guò)網(wǎng)頁(yè)讓用戶進(jìn)行支付)

// 注意:如果是通過(guò)網(wǎng)頁(yè)支付完成,那么會(huì)回調(diào)該block:callback

[Objective-C] 純文本查看 復(fù)制代碼

 [[AlipaySDK defaultService] payOrder:orderString fromScheme:@"jingdong" callback:^(NSDictionary *resultDic) { }];

在AppDelegate.m

[Objective-C] 純文本查看 復(fù)制代碼

// 當(dāng)通過(guò)別的應(yīng)用程序,將該應(yīng)用程序打開(kāi)時(shí),會(huì)調(diào)用該方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{ // 當(dāng)用戶通過(guò)支付寶客戶端進(jìn)行支付時(shí),會(huì)回調(diào)該block:standbyCallback 
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); }]; return YES;}

9、遠(yuǎn)程推送

當(dāng)服務(wù)端遠(yuǎn)程向APNS推送至一臺(tái)離線的設(shè)備時(shí),蘋(píng)果服務(wù)器Qos組件會(huì)自動(dòng)保留一份最新的通知,等設(shè)備上線后,Qos將把推送發(fā)送到目標(biāo)設(shè)備上

遠(yuǎn)程推送的基本過(guò)程

1.客戶端的app需要將用戶的UDID和app的bundleID發(fā)送給apns服務(wù)器,進(jìn)行注冊(cè),apns將加密后的device Token返回給app

2.app獲得device Token后,上傳到公司服務(wù)器

3.當(dāng)需要推送通知時(shí),公司服務(wù)器會(huì)將推送內(nèi)容和device Token一起發(fā)給apns服務(wù)器

4.apns再將推送內(nèi)容送到客戶端上

創(chuàng)建證書(shū)的流程:

1.打開(kāi)鑰匙串,生成CertificateSigningRequest.certSigningRequest文件

2.將CertificateSigningRequest.certSigningRequest上傳進(jìn)developer,導(dǎo)出.cer文件

3.利用CSR導(dǎo)出P12文件

4.需要準(zhǔn)備下設(shè)備token值(無(wú)空格)

5.使用OpenSSL合成服務(wù)器所使用的推送證書(shū)

本地app代碼參考

1.注冊(cè)遠(yuǎn)程通知

[Objective-C] 純文本查看 復(fù)制代碼

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions//中注冊(cè)遠(yuǎn)程通知
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}

2,實(shí)現(xiàn)幾個(gè)代理方法:

[Objective-C] 純文本查看 復(fù)制代碼

//獲取deviceToken令牌  
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken  
{  
//獲取設(shè)備的deviceToken唯一編號(hào)  
NSLog(@"deviceToken=%@",deviceToken);  
NSString *realDeviceToken=[NSString stringWithFormat:@"%@",deviceToken];  
//去除<>  
realDeviceToken = [realDeviceToken stringByReplacingOccurrencesOfString:@"<" withString:@""];  
realDeviceToken = [realDeviceToken stringByReplacingOccurrencesOfString:@">" withString:@""];  
NSLog(@"realDeviceToken=%@",realDeviceToken);  
[[NSUserDefaults standardUserDefaults] setValue:realDeviceToken forKey:@"DeviceToken"];  //要發(fā)送給服務(wù)器
}  

 //獲取令牌出錯(cuò)  
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error  
{  
//注冊(cè)遠(yuǎn)程通知設(shè)備出錯(cuò)  
NSLog(@"RegisterForRemoteNotification error=%@",error);  
}  
//在應(yīng)用在前臺(tái)時(shí)受到消息調(diào)用  
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo  
{  
 //打印推送的消息  
NSLog(@"%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]):  
}

配置后臺(tái)模式

<ignore_js_op>[圖片上傳中...(image-763ce2-1554465783411-0)]</ignore_js_op>

一般我們是使用開(kāi)發(fā)版本的Provisioning做推送測(cè)試,如果沒(méi)有問(wèn)題,再使用發(fā)布版本證書(shū)的時(shí)候一般也應(yīng)該是沒(méi)有問(wèn)題的。為了以防萬(wàn)一,我們可以在越獄的手機(jī)上安裝我們的使用發(fā)布版證書(shū)的ipa文件(最好使用debug版本,并打印出獲取到的deviceToken),安裝成功后在;XCode->Window->Organizer-找到對(duì)應(yīng)的設(shè)備查看console找到打印的deviceToken。

在后臺(tái)的推送程序中使用發(fā)布版制作的證書(shū)并使用該deviceToken做推送服務(wù).

使用開(kāi)發(fā)和發(fā)布證書(shū)獲取到的deviceToken是不一樣的。

10、@protocol 和 category 中如何使用 @property

1)在protocol中使用property只會(huì)生成setter和getter方法聲明,我們使用屬性的目的,是希望遵守我協(xié)議的對(duì)象能實(shí)現(xiàn)該屬性

2)category 使用 @property 也是只會(huì)生成setter和getter方法的聲明,如果我們真的需要給category增加屬性的實(shí)現(xiàn),需要借助于運(yùn)行時(shí)的兩個(gè)函數(shù):

①objc_setAssociatedObject

②objc_getAssociatedObject

文章來(lái)源網(wǎng)絡(luò)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,786評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,986評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,204評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,964評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,354評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,554評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,106評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,918評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,093評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,342評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,755評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,009評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,839評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,107評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容