iOS開發之第三方分享QQ分享,史上最新最全第三方分享QQ方式實現
專案搭建參考: (包含QQ登入原始碼下載 、 QQ sdk整合)
分享第三方分享之QQ分享各種坑的總結:
1. 分享老是提示未註冊QQ,解決辦法就是在程式已啟動,就向QQ進行授權。程式碼如下
QQ未註冊錯誤代號 EQQAPIAPPNOTREGISTED- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[TencentOAuth alloc] initWithAppId:TENCENT_CONNECT_APP_KEY andDelegate:self]; return YES; }
2. 分享的時候, 不跳轉到QQ介面,解決辦法就是在openurl中,新增如下程式碼:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{ /** 處理由手Q喚起的跳轉請求 \param url 待處理的url跳轉請求 \param delegate 第三方應用用於處理來至QQ請求及響應的委託物件 \return 跳轉請求處理結果,YES表示成功處理,NO表示不支援的請求協議或處理失敗 */ if ([url.absoluteString hasPrefix:[NSString stringWithFormat:@"tencent%@",TENCENT_CONNECT_APP_KEY]]) { [QQApiInterface handleOpenURL:url delegate:self]; return [TencentOAuth HandleOpenURL:url]; } return YES; }
3. iOS9白名單的問題,沒有吧QQ的相關白名單填完成。 完成的如下。
<key>LSApplicationQueriesSchemes</key> <array> <string>mqqapi</string> <string>mqq</string> <string>mqqOpensdkSSoLogin</string> <string>mqqconnect</string> <string>mqqopensdkdataline</string> <string>mqqopensdkgrouptribeshare</string> <string>mqqopensdkfriend</string> <string>mqqopensdkapi</string> <string>mqqopensdkapiV2</string> <string>mqqopensdkapiV3</string> <string>mqzoneopensdk</string> <string>wtloginmqq</string> <string>wtloginmqq2</string> <string>mqqwpa</string> <string>mqzone</string> <string>mqzonev2</string> <string>mqzoneshare</string> <string>wtloginqzone</string> <string>mqzonewx</string> <string>mqzoneopensdkapiV2</string> <string>mqzoneopensdkapi19</string> <string>mqzoneopensdkapi</string> <string>mqzoneopensdk</string> </array>
進入正題:
分享的物件包含:
QQApiTextObject 文字物件
QQApiURLObject URL物件型別
QQApiExtendObject 擴充套件資料型別
QQApiImageObject 圖片物件
QQApiImageArrayForQZoneObject 圖片陣列物件 用於分享圖片到空間,走寫說說路徑,是一個指定為圖片型別的,當圖片陣列為空時,預設走文字寫說說
QQApiVideoForQZoneObject 視訊物件
QQApiWebImageObject 網路圖片物件
QQApiFileObject 本地檔案物件
QQApiAudioObject 音訊URL物件
QQApiVideoObject 視訊URL物件 :用於分享目標內容為視訊的URL的物件
QQApiNewsObject 新聞URL物件
等等。
相關的分享物件的許可權看下圖:
分享的核心程式碼為: (分享 新聞URL物件為例子)
/**
分享 新聞URL物件 。
獲取一個autorelease的<code>QQApiAudioObject</code>
@param url 音訊內容的目標URL
@param title 分享內容的標題
@param description 分享內容的描述
@param previewURL 分享內容的預覽影象URL
@note 如果url為空,呼叫<code>QQApi#sendMessage:</code>時將返回FALSE
*/
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
NSURL *preimageUrl = [NSURL URLWithString:@"http://www.sizzee.com/index.php/catalog/product/view/id/55730/s/10196171/?SID=au0lhpg54f11nenmrjvhsh0rq6?uk=Y3VzdG9tZXJfaWQ9Mjc0fHByb2R1Y3RfaWQ9NTU3MzA"];
QQApiNewsObject* img = [QQApiNewsObject objectWithURL:url title:@"測試分享" description:[NSString stringWithFormat:@"分享內容------新聞URL物件分享 ------test"] previewImageURL:preimageUrl];
//請求幫助類,分享的所有基礎物件,都要封裝成這種請求物件。
SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:img];
QQApiSendResultCode sent = [QQApiInterface sendReq:req];
//通過自定義的qqdelegate來通知本controller,是否成功分享
appdelegate.qqDelegate = self;
NSLog(@"QQApiSendResultCode %d",sent);
[self handleSendResult:sent];
/* QQApiSendResultCode 說明
EQQAPISENDSUCESS = 0, 操作成功
EQQAPIQQNOTINSTALLED = 1, 沒有安裝QQ
EQQAPIQQNOTSUPPORTAPI = 2,
EQQAPIMESSAGETYPEINVALID = 3, 引數錯誤
EQQAPIMESSAGECONTENTNULL = 4,
EQQAPIMESSAGECONTENTINVALID = 5,
EQQAPIAPPNOTREGISTED = 6, 應用未註冊
EQQAPIAPPSHAREASYNC = 7,
EQQAPIQQNOTSUPPORTAPI_WITH_ERRORSHOW = 8,
EQQAPISENDFAILD = -1, 傳送失敗
//qzone分享不支援text型別分享
EQQAPIQZONENOTSUPPORTTEXT = 10000,
//qzone分享不支援image型別分享
EQQAPIQZONENOTSUPPORTIMAGE = 10001,
//當前QQ版本太低,需要更新至新版本才可以支援
EQQAPIVERSIONNEEDUPDATE = 10002,
*/
}
- (void)handleSendResult:(QQApiSendResultCode)sendResult
{
switch (sendResult)
{
case EQQAPIAPPNOTREGISTED:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"App未註冊" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIMESSAGECONTENTINVALID:
case EQQAPIMESSAGECONTENTNULL:
case EQQAPIMESSAGETYPEINVALID:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"傳送引數錯誤" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIQQNOTINSTALLED:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"未安裝手Q" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIQQNOTSUPPORTAPI:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"API介面不支援" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPISENDFAILD:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"傳送失敗" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIVERSIONNEEDUPDATE:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"當前QQ版本太低,需要更新" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
default:
{
break;
}
}
}
上面提到了分享。那麼如何來監聽分享是否成功呢。這就要回到我們的appdelegate裡面。監聽
- (void)onResp:(QQBaseResp *)resp
appdelegate中的相關程式碼如下:
**
處理來至QQ的響應
*/
- (void)onResp:(QQBaseResp *)resp{
NSLog(@" ----resp %@",resp);
// SendMessageToQQResp應答幫助類
if ([resp.class isSubclassOfClass: [SendMessageToQQResp class]]) { //QQ分享迴應
if (_qqDelegate) {
if ([_qqDelegate respondsToSelector:@selector(shareSuccssWithQQCode:)]) {
SendMessageToQQResp *msg = (SendMessageToQQResp *)resp;
NSLog(@"code %@ errorDescription %@ infoType %@",resp.result,resp.errorDescription,resp.extendInfo);
[_qqDelegate shareSuccssWithQQCode:[msg.result integerValue]];
}
}
}
}
完整的程式碼如下
appdelegate.h
//
// AppDelegate.h
// QQLoginDemo
//
// Created by 張國榮 on 16/6/17.
// Copyright © 2016年 BateOrganization. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol QQShareDelegate <NSObject>
-(void)shareSuccssWithQQCode:(NSInteger)code;
@end
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (weak , nonatomic) id<QQShareDelegate> qqDelegate;
@end
appdelegate,m
//
// AppDelegate.m
// QQLoginDemo
//
// Created by 張國榮 on 16/6/17.
// Copyright © 2016年 BateOrganization. All rights reserved.
//
#import "AppDelegate.h"
#import <TencentOpenAPI/QQApiInterface.h>
#import <TencentOpenAPI/TencentOAuth.h>
#define TENCENT_CONNECT_APP_KEY @"app id"
@interface AppDelegate ()<QQApiInterfaceDelegate,TencentSessionDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// [QQApiInterface ]
[[TencentOAuth alloc] initWithAppId:TENCENT_CONNECT_APP_KEY andDelegate:self];
// NSLog(@"%@",oauth.appId);
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
/**
處理由手Q喚起的跳轉請求
\param url 待處理的url跳轉請求
\param delegate 第三方應用用於處理來至QQ請求及響應的委託物件
\return 跳轉請求處理結果,YES表示成功處理,NO表示不支援的請求協議或處理失敗
*/
if ([url.absoluteString hasPrefix:[NSString stringWithFormat:@"tencent%@",TENCENT_CONNECT_APP_KEY]]) {
[QQApiInterface handleOpenURL:url delegate:self];
return [TencentOAuth HandleOpenURL:url];
}
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
/**
處理由手Q喚起的跳轉請求
\param url 待處理的url跳轉請求
\param delegate 第三方應用用於處理來至QQ請求及響應的委託物件
\return 跳轉請求處理結果,YES表示成功處理,NO表示不支援的請求協議或處理失敗
*/
if ([url.absoluteString hasPrefix:[NSString stringWithFormat:@"tencent%@",TENCENT_CONNECT_APP_KEY]]) {
[QQApiInterface handleOpenURL:url delegate:self];
return [TencentOAuth HandleOpenURL:url];
}
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{
/**
處理由手Q喚起的跳轉請求
\param url 待處理的url跳轉請求
\param delegate 第三方應用用於處理來至QQ請求及響應的委託物件
\return 跳轉請求處理結果,YES表示成功處理,NO表示不支援的請求協議或處理失敗
*/
if ([url.absoluteString hasPrefix:[NSString stringWithFormat:@"tencent%@",TENCENT_CONNECT_APP_KEY]]) {
[QQApiInterface handleOpenURL:url delegate:self];
return [TencentOAuth HandleOpenURL:url];
}
return YES;
}
/**
處理來至QQ的請求
*/
- (void)onReq:(QQBaseReq *)req{
NSLog(@" ----req %@",req);
}
/**
處理來至QQ的響應
*/
- (void)onResp:(QQBaseResp *)resp{
NSLog(@" ----resp %@",resp);
// SendMessageToQQResp應答幫助類
if ([resp.class isSubclassOfClass: [SendMessageToQQResp class]]) { //QQ分享迴應
if (_qqDelegate) {
if ([_qqDelegate respondsToSelector:@selector(shareSuccssWithQQCode:)]) {
SendMessageToQQResp *msg = (SendMessageToQQResp *)resp;
NSLog(@"code %@ errorDescription %@ infoType %@",resp.result,resp.errorDescription,resp.extendInfo);
[_qqDelegate shareSuccssWithQQCode:[msg.result integerValue]];
}
}
}
}
/**
處理QQ線上狀態的回撥
*/
- (void)isOnlineResponse:(NSDictionary *)response{
}
@end
viewcontroller.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
viewcontroller.m
#import "ViewController.h"
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/TencentApiInterface.h>
#import <TencentOpenAPI/QQApiInterfaceObject.h>
#import <TencentOpenAPI/QQApiInterface.h>
#import "AppDelegate.h"
#define APP_ID @"app id"
@interface ViewController ()<TencentSessionDelegate,QQShareDelegate>
{
TencentOAuth *_tencentOAuth;
NSMutableArray *_permissionArray; //許可權列表
AppDelegate *appdelegate;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
appdelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
self.view.backgroundColor = [UIColor whiteColor];
}
#pragma mark QQ登入
- (IBAction)loginAction:(id)sender {
_tencentOAuth=[[TencentOAuth alloc]initWithAppId:APP_ID andDelegate:self];
//設定許可權資料 , 具體的許可權名,在sdkdef.h 檔案中檢視。
_permissionArray = [NSMutableArray arrayWithObjects: kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,nil];
//登入操作
[_tencentOAuth authorize:_permissionArray inSafari:NO];
}
/**
* 登入成功後的回撥
*/
- (void)tencentDidLogin{
/** Access Token憑證,用於後續訪問各開放介面 */
if (_tencentOAuth.accessToken) {
//獲取使用者資訊。 呼叫這個方法後,qq的sdk會自動呼叫
//- (void)getUserInfoResponse:(APIResponse*) response
//這個方法就是 使用者資訊的回撥方法。
[_tencentOAuth getUserInfo];
}else{
NSLog(@"accessToken 沒有獲取成功");
}
}
/**
* 登入失敗後的回撥
* \param cancelled 代表使用者是否主動退出登入
*/
- (void)tencentDidNotLogin:(BOOL)cancelled{
if (cancelled) {
NSLog(@" 使用者點選取消按鍵,主動退出登入");
}else{
NSLog(@"其他原因, 導致登入失敗");
}
}
/**
* 登入時網路有問題的回撥
*/
- (void)tencentDidNotNetWork{
NSLog(@"沒有網路了, 怎麼登入成功呢");
}
/**
* 因使用者未授予相應許可權而需要執行增量授權。在使用者呼叫某個api介面時,如果伺服器返回操作未被授權,則觸發該回調協議介面,由第三方決定是否跳轉到增量授權頁面,讓使用者重新授權。
* \param tencentOAuth 登入授權物件。
* \param permissions 需增量授權的許可權列表。
* \return 是否仍然回撥返回原始的api請求結果。
* \note 不實現該協議介面則預設為不開啟增量授權流程。若需要增量授權請呼叫\ref TencentOAuth#incrAuthWithPermissions: \n注意:增量授權時使用者可能會修改登入的帳號
*/
- (BOOL)tencentNeedPerformIncrAuth:(TencentOAuth *)tencentOAuth withPermissions:(NSArray *)permissions{
// incrAuthWithPermissions是增量授權時需要呼叫的登入介面
// permissions是需要增量授權的許可權列表
[tencentOAuth incrAuthWithPermissions:permissions];
return NO; // 返回NO表明不需要再回傳未授權API介面的原始請求結果;
// 否則可以返回YES
}
/**
* [該邏輯未實現]因token失效而需要執行重新登入授權。在使用者呼叫某個api介面時,如果伺服器返回token失效,則觸發該回調協議介面,由第三方決定是否跳轉到登入授權頁面,讓使用者重新授權。
* \param tencentOAuth 登入授權物件。
* \return 是否仍然回撥返回原始的api請求結果。
* \note 不實現該協議介面則預設為不開啟重新登入授權流程。若需要重新登入授權請呼叫\ref TencentOAuth#reauthorizeWithPermissions: \n注意:重新登入授權時使用者可能會修改登入的帳號
*/
- (BOOL)tencentNeedPerformReAuth:(TencentOAuth *)tencentOAuth{
return YES;
}
/**
* 使用者通過增量授權流程重新授權登入,token及有效期限等資訊已被更新。
* \param tencentOAuth token及有效期限等資訊更新後的授權例項物件
* \note 第三方應用需更新已儲存的token及有效期限等資訊。
*/
- (void)tencentDidUpdate:(TencentOAuth *)tencentOAuth{
NSLog(@"增量授權完成");
if (tencentOAuth.accessToken
&& 0 != [tencentOAuth.accessToken length])
{ // 在這裡第三方應用需要更新自己維護的token及有效期限等資訊
// **務必在這裡檢查使用者的openid是否有變更,變更需重新拉取使用者的資料等資訊** _labelAccessToken.text = tencentOAuth.accessToken;
}
else
{
NSLog(@"增量授權不成功,沒有獲取accesstoken");
}
}
/**
* 使用者增量授權過程中因取消或網路問題導致授權失敗
* \param reason 授權失敗原因,具體失敗原因參見sdkdef.h檔案中\ref UpdateFailType
*/
- (void)tencentFailedUpdate:(UpdateFailType)reason{
switch (reason)
{
case kUpdateFailNetwork:
{
// [email protected]"增量授權失敗,無網路連線,請設定網路";
NSLog(@"增量授權失敗,無網路連線,請設定網路");
break;
}
case kUpdateFailUserCancel:
{
// [email protected]"增量授權失敗,使用者取消授權";
NSLog(@"增量授權失敗,使用者取消授權");
break;
}
case kUpdateFailUnknown:
default:
{
NSLog(@"增量授權失敗,未知錯誤");
break;
}
}
}
#pragma mark 登入成功後,回撥 - 返回對應QQ的相關資訊
/**
* 獲取使用者個人資訊回撥
* \param response API返回結果,具體定義參見sdkdef.h檔案中\ref APIResponse
* \remarks 正確返回示例: \snippet example/getUserInfoResponse.exp success
* 錯誤返回示例: \snippet example/getUserInfoResponse.exp fail
*/
- (void)getUserInfoResponse:(APIResponse*) response{
//這裡 與自己伺服器進行對接,看怎麼利用這獲取到的個人資訊。
NSDictionary *dic = response.jsonResponse;
NSLog(@" response %@",dic);
}
#pragma mark QQ分享
- (IBAction)QQshareAction:(id)sender {
/**
分享 新聞URL物件 。
獲取一個autorelease的<code>QQApiAudioObject</code>
@param url 音訊內容的目標URL
@param title 分享內容的標題
@param description 分享內容的描述
@param previewURL 分享內容的預覽影象URL
@note 如果url為空,呼叫<code>QQApi#sendMessage:</code>時將返回FALSE
*/
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
NSURL *preimageUrl = [NSURL URLWithString:@"http://www.sizzee.com/index.php/catalog/product/view/id/55730/s/10196171/?SID=au0lhpg54f11nenmrjvhsh0rq6?uk=Y3VzdG9tZXJfaWQ9Mjc0fHByb2R1Y3RfaWQ9NTU3MzA"];
QQApiNewsObject* img = [QQApiNewsObject objectWithURL:url title:@"測試分享" description:[NSString stringWithFormat:@"分享內容------新聞URL物件分享 ------test"] previewImageURL:preimageUrl];
//請求幫助類,分享的所有基礎物件,都要封裝成這種請求物件。
SendMessageToQQReq* req = [SendMessageToQQReq reqWithContent:img];
QQApiSendResultCode sent = [QQApiInterface sendReq:req];
//通過自定義的qqdelegate來通知本controller,是否成功分享
appdelegate.qqDelegate = self;
NSLog(@"QQApiSendResultCode %d",sent);
[self handleSendResult:sent];
/* QQApiSendResultCode 說明
EQQAPISENDSUCESS = 0, 操作成功
EQQAPIQQNOTINSTALLED = 1, 沒有安裝QQ
EQQAPIQQNOTSUPPORTAPI = 2,
EQQAPIMESSAGETYPEINVALID = 3, 引數錯誤
EQQAPIMESSAGECONTENTNULL = 4,
EQQAPIMESSAGECONTENTINVALID = 5,
EQQAPIAPPNOTREGISTED = 6, 應用未註冊
EQQAPIAPPSHAREASYNC = 7,
EQQAPIQQNOTSUPPORTAPI_WITH_ERRORSHOW = 8,
EQQAPISENDFAILD = -1, 傳送失敗
//qzone分享不支援text型別分享
EQQAPIQZONENOTSUPPORTTEXT = 10000,
//qzone分享不支援image型別分享
EQQAPIQZONENOTSUPPORTIMAGE = 10001,
//當前QQ版本太低,需要更新至新版本才可以支援
EQQAPIVERSIONNEEDUPDATE = 10002,
*/
}
- (void)handleSendResult:(QQApiSendResultCode)sendResult
{
switch (sendResult)
{
case EQQAPIAPPNOTREGISTED:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"App未註冊" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIMESSAGECONTENTINVALID:
case EQQAPIMESSAGECONTENTNULL:
case EQQAPIMESSAGETYPEINVALID:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"傳送引數錯誤" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIQQNOTINSTALLED:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"未安裝手Q" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIQQNOTSUPPORTAPI:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"API介面不支援" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPISENDFAILD:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"傳送失敗" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
case EQQAPIVERSIONNEEDUPDATE:
{
UIAlertView *msgbox = [[UIAlertView alloc] initWithTitle:@"Error" message:@"當前QQ版本太低,需要更新" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];
[msgbox show];
break;
}
default:
{
break;
}
}
}
#pragma mark QQ分享回撥代理
/* 返回碼 對照說明
0 成功
-1 引數錯誤
-2 該群不在自己的群列表裡面
-3 上傳圖片失敗
-4 使用者放棄當前操作
-5 客戶端內部處理錯誤
*/
-(void)shareSuccssWithQQCode:(NSInteger)code{
NSLog(@"code %ld",(long)code);
if (code == 0) {
UIAlertView *aler = [[UIAlertView alloc]initWithTitle:@"警告" message:@"分享成功" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[aler show];
}else{
UIAlertView *aler = [[UIAlertView alloc]initWithTitle:@"警告" message:@"分享失敗" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[aler show];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
大功告成。
相關推薦
iOS開發之第三方分享QQ分享,史上最新最全第三方分享QQ方式實現
專案搭建參考: (包含QQ登入原始碼下載 、 QQ sdk整合) 分享第三方分享之QQ分享各種坑的總結: 1. 分享老是提示未註冊QQ,解決辦法就是在程式已啟動,就向QQ進行授權。程式碼如下 - (BOOL)application:(UIApplication *
iOS開發之第三方分享微信分享、朋友圈分享,史上最新最全第三方分享微信方式實現、朋友圈方式實現
微信分享前提: 1.需要成功在微信開發者平臺註冊了賬號, 並取的對應的 appkey appSecret。 2. 針對iOS9 添加了微信的白名單,以及設定了 scheme url 。 這都可以參照上面的連結,進行設定好。 3. 分享不跳轉的時
iOS開發之第三方支付微信支付教程,史上最新最全第三方微信支付方式實現、微信整合教程,微信實現流程
1. 微信支付微信支付前奏大致流程為 : 1. 公司需要到微信進行申請app支付功能 , 獲得appid和微信支付商戶號(mch_id)和API祕鑰(key) 、 Appsecret(secret),開發中用到的,很重要 appid:appid是微信公眾賬號
iOS開發之MAC的記憶體清理,Xcode清理
此文章僅適用於適用於使用Xcode的開發者。 長期不清理Xcode中的一些檔案你會發現自己的mac硬碟越來越小,而且是這個其他佔了絕大部分的硬碟,在網上搜索了很多辦法都沒找到如何清理這些其他 後來來來回回在資料夾中找發現~/Library/Developer/Xcode這個Xcode資料夾大的驚
IOS開發之介面生命週期——init,viewDidAppear,viewWill(dis)Appear,loadView,viewDid(un)Load,dealloc
一、生命週期 當一個檢視控制器被建立,並在螢幕上顯示的時候。 程式碼的執行順序 1、 alloc 建立物件,分配空間 2、init (initWithNibName) 初始化物件,初始化資料 3、loadVie
ios開發之人臉識別(給眼睛打上馬賽克)
#import "ViewController.h" @interfaceViewController () @end @implementationViewController - (v
ios開發之--UIDocumentInteractionController的使用(實現更多分享服務)
void cnblogs 實例 內容 main 華麗 例如 一個 img 最近在做項目的時候,碰到這樣一個需求,就是本地生成pdf文件,然後本地打開,經過測試發現,pdf文件是無法保存到相冊裏面的,只能存到手機裏面,鑒於蘋果的存儲機制,需要取出來,進行本地展示,可以直接傳到
iOS開發之ReactiveCocoa下的MVVM(乾貨分享)
最近工作比較忙,但還是出來更新部落格了,今天給大家分享一些ReactiveCocoa以及MVVM的一些東西,幹活還是比較足的。在之前發表過一篇博文,名字叫做,大體上講的就是使用Block回撥的方式實現MVVM的。在寫上篇文章時也知道有ReactiveCocoa這個函式響應式程式
iOS開發之三方分享(shareSDK)
1、專案已一開始要的比較急,做三方分享的時候時候使用的系統自帶的分享功能,但是有時候title會獲取不到,出現無標題的狀態,轉發系統的分享連結有時候,title會讀取連結的title,使用起來不是很方便,所以稍微有時間就介入了三方的SDK。 2、以前使用的是友盟的share
ios開發之--textview意見反饋頁面(占位label,字數統計,提交按鈕的交互設置)
ould 技術 ima out == img ios開發 del 分享圖片 記錄一個頁面的功能: textview的占位符,字數統計,提交按鈕的交互設置,具體效果圖如下: 輸入效果: 具體實現代碼如下: 1,設置代理 @interface FKViewControll
iOS開發之OC與swift開發混編教程,代理的相互呼叫,block的實現。OC呼叫Swift中的代理, OC呼叫Swift中的Block 閉包
本文章將從兩個方向分別介紹 OC 與 swift 混編 1. 第一個方向從 swift工程 中引入 oc類 1. 1 如何在swift的類中使用oc類 1.2 如何在swift中實現oc的代理方法 &
iOS開發之如何優雅的替換工程裡所有的系統彈框UIAlertView,UIActionSheet,UIAlertController 的原理
現在又要替換UIAlertView和UIActionSheet UIActionSheet使用的不多,按照系統的屬性方法名,重新定義一個類 實現一下就好,和UISwitch那個類似。 這裡以UIAlertView為例,因為它使用的特別多,直接在工程裡能搜到500多個,
iOS開發之(玩轉藍芽)不看此文,枉做開發
前言: 之前詳細談過不少關於HTTP協議的知識點,TCP/IP也通過tcpdump做過簡單的介紹,但網路協議的本質其實是連線,裝置或者端之間連線的方式有多種,常見的http或者基於tcp的socket只是森林一葉,還有些不那麼常見的協議比如藍芽。適當腦洞,也能玩出不少新花樣
玩轉iOS開發:《使用系統自帶的UIActivityViewController和UIActivity進行內容分享》
目錄 簡介 這段時間有很多朋友都問我關於怎麼去整合ShareSDK或者友盟社會化分享SDK的問題, 其實我想說, Apple一開始就提供了一個類, 供我們去使用分享了, 在iOS 6之後更加增強了這個類, 使我們不再需要整合第三方的, 而且還支援自定義分享的item. 作者感言 在我寫這篇文章的時
iOS開發之三個Button實現圖片無限輪播(參考手機淘寶,Swift版)
這兩天使用Reveal工具檢視"手機淘寶"App的UI層次時,發現其圖片輪播使用了三個UIButton的複用來實現的圖片迴圈無縫滾動。於是乎就有了今天這篇部落格,看到“手機淘寶”這個幻燈片的UI層級時,就想要動手使用三個Button來實現一下,當然本篇部落格使用是Swift語言,思路就是使用三個Button進
iOS開發之Swift標籤欄按鈕UITabBarItem樣式修改(圖示文字尺寸,顏色等)
import UIKit class MainTabViewController:UITabBarController { override func viewDidLoad() { super.viewDidLoad() // 一共包含了兩個檢視
2018年最全iOS開發之第三方庫
最全iOS開發之第三方庫最新增加EAIntroView 一個靈活的介紹介面,可以用作引導頁UI下拉重新整理EGOTableViewPullRefresh– 最早的下拉重新整理控制元件。SVPullToRefresh– 下拉重新整理控制元件。MJRefresh– 僅需一行程式碼
iOS開發之OC與swift開發混編教程,代理的相互呼叫,block的實現。OC呼叫Swift中的代理, OC呼叫Swift中的Block 閉包,swift 3.0
最新一些學妹問起,所以抽點時間來寫的,適合入門級別的swift 與 OC 混編 的程式猿。 本文章將從兩個方向分別介紹 OC 與 swift 混編 1. 第一個方向從 swift工程 中引入 oc類 1. 1 如何在swift的類中使用oc類 1
iOS開發之自定義鍵盤(數字,字母型別等隨意切換)
專案開發很多時候用系統給的鍵盤不是很滿足自身實際需求,那就自定義一個吧: 方法其實很簡單,重新定義一個view,繼承UItextfield,把UI設計好的需求鍵盤加入新的otherKeyboardView,然後執行程式碼: self.inputView =self.oth
iOS開發之應用內檢測手機鎖屏,解鎖狀態
iPhone的鎖屏監測分為兩種方式監聽: 1. 程式在前臺,這種比較簡單。直接使用Darwin層的通知就可以了: #import <notify.h> #define NotificationLock CFSTR("com.apple.springboa