ios - SLComposeViewController共享教程




ios6 social-framework (4)

有關此框架的詳細信息,請參閱Apple的Social Framework類參考

其他教程:

  1. http://soulwithmobiletechnology.blogspot.com/2012/07/tutorial-how-to-use-inbuilt.html
  2. http://www.mobile.safilsunny.com/iphone/integrating-facebook-ios/
  3. http://rudeboy-quickies.blogspot.com/2012/06/steps-to-integrate-facebook-in-ios6.html
  4. https://developer.apple.com/videos/wwdc/2012/?id=306

對於這個例子,我們將使用SLComposeViewControllerSLServiceTypeFacebook 。 如果您希望使用Twitter或SinaWeibo,只需將SLServiceType更改為以下其中一項:

  • SLServiceTypeFacebook
  • SLServiceTypeSinaWeibo
  • SLServiceTypeTwitter

iOS 6使用SLComposeViewController直接發佈到Facebook,Twitter或新浪微博非常簡單。 這與iOS 5的TWTweetComposeViewController非常類似。

首先,在你的視圖控制器的頭文件(.h)中#import社會框架和帳戶框架。

#import <Social/Social.h>

#import <Accounts/Accounts.h>

在這裡,我們將聲明一個簡單的UIButton和一個IBAction ,我們稍後將鏈接到該按鈕以及一個void (sharingStatus),它將用於檢查所選的共享服務是否可用。

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UIButton *easyFacebookButton;
- (IBAction)facebookPost:(id)sender;
- (void)sharingStatus;
@end

@implementation ViewController

然後,在您的實現文件(.m)中,我們將首先實現我們在頭文件中聲明的(sharingStatus)void。 sharingStatus使用SLComposeViewControllerisAvailableForServiceType BOOL返回是否可以發佈到其參數中指定的服務。 在這種情況下,我們將使用服務類型SLServiceTypeFacebook 。 如果該服務可用,則後置按鈕將以1.0f的阿爾法值被啟用,並且如果該服務不可用,則該按鈕將被禁用其α值被設置為0.5f。

- (void)sharingStatus {
    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
        NSLog(@"service available");
        self.easyFacebookButton.enabled = YES;
        self.easyFacebookButton.alpha = 1.0f;
    } else {
        self.easyFacebookButton.enabled = NO;
        self.easyFacebookButton.alpha = 0.5f;
    }
}

在這裡,我們將設置IBAction來調用作曲家。 對於良好的做法,我們將再次檢查isAvailableForServiceType ,以避免調用isAvailableForServiceType來獲取不可用的服務類型。 (在最後一次檢查過程中發生了錯誤,或者在點擊發布按鈕和作曲者all / init之間以某種方式改變了可用性,下面的代碼已經設置為顯示帶有文本的Facebook作曲家工作表,一個圖像和一個鏈接,這個動作還為作曲家取消和完成的結果使用了一個完成處理程序。

- (IBAction)facebookPost:(id)sender {

    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {

        SLComposeViewController *mySLComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];

        [mySLComposerSheet setInitialText:@"iOS 6 Social Framework test!"];

        [mySLComposerSheet addImage:[UIImage imageNamed:@"myImage.png"]];

        [mySLComposerSheet addURL:[NSURL URLWithString:@"http://stackoverflow.com/questions/12503287/tutorial-for-slcomposeviewcontroller-sharing"]];

        [mySLComposerSheet setCompletionHandler:^(SLComposeViewControllerResult result) {

             switch (result) {
                 case SLComposeViewControllerResultCancelled:
                     NSLog(@"Post Canceled");
                     break;
                 case SLComposeViewControllerResultDone:
                     NSLog(@"Post Sucessful");
                     break;

                 default:
                     break;
             }
         }];

        [self presentViewController:mySLComposerSheet animated:YES completion:nil];
    }
}

viewWillAppear我們將向ACAccountStoreDidChangeNotification註冊一個觀察者,以便在帳戶信息更改時通知應用程序。 這個觀察者將在viewDidDisappear被移除。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sharingStatus) name:ACAccountStoreDidChangeNotification object:nil];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:ACAccountStoreDidChangeNotification];
}

最後,打開界面生成器並添加一個UIButton ,它將成為發布按鈕。 然後在連接檢查器中將我們之前創建的IBOutletIBAction鏈接到按鈕,就是這樣! 你完成了!

我需要遵循什麼步驟才能使用iOS 6的新SLComposeViewController發佈到Facebook,Twitter或新浪微博?


SLComposeViewController的安全使用

if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
    {
        SLComposeViewController *fbPost = [SLComposeViewController
                                               composeViewControllerForServiceType: SLServiceTypeFacebook];
        [fbPost setInitialText:@"Text You want to Share"];
        [fbPost addImage:[UIImage imageNamed:@"shareImage.png"]];
        [self presentViewController:fbPost animated:YES completion:nil];
        [fbPost setCompletionHandler:^(SLComposeViewControllerResult result) {
            switch (result) {
                case SLComposeViewControllerResultCancelled:
                    NSLog(@"Post Canceled");
                    break;
                case SLComposeViewControllerResultDone:
                    NSLog(@"Post Sucessful");
                    break;
                default:
                    break;
            }
            [self dismissViewControllerAnimated:YES completion:nil];
        }];
    }

只需使用此代碼在Facebook上分享。

SLComposeViewController *controllerSLC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[controllerSLC setInitialText:@"First post from my iPhone app"];
[controllerSLC addURL:[NSURL URLWithString:@"http://www.appcoda.com"]];
[controllerSLC addImage:[UIImage imageNamed:@"test.jpg"]];
[self presentViewController:controllerSLC animated:YES completion:Nil];

如果你想要這個Twitter的話,只需更改SLServiceTypeTwitter。


當觸發segue時,將“數據傳遞到目標控制器”將通過重寫方法prepareForSegue:sender:來實現。

通常,您將數據而不是源視圖控制器傳遞到目標視圖控制器。 “數據”可能是您的應用程序“模型”的某個方面。 它是像“User”這樣的對象,或者可能是包含“User”等的數組。

目標視圖控制器不應具有視圖控制器的任何知識。 這意味著,目標視圖控制器不需要導入源視圖控制器的標頭。

另一方面, 視圖控制器可以知道目標視圖控制器的具體類或目標視圖控制器的類,因此將導入目標視圖控制器的頭。

請參閱: 觸發Segue時配置目標控制器

如果在源和目標之間需要某種“通信協議”,則可以使用委派與其他視圖控制器進行通信。 這涉及@protocol的定義(例如,具有方法doneButton )和在目標視圖控制器中定義的屬性delegate 。 如果目標視圖控制器特定於目標視圖控制器,則應在目標視圖控制器的標頭中定義該協議。 通常,您從目標控制器的角度定義協議,而不是從源控制器的要求定義協議。

源視圖控制器然後創建一個委託(除非它本身就是它)並設置目標視圖控制器的delegate 。 目標視圖控制器將委託方法發送給委託,委託處理它。

現在,將“數據”從VC_A傳遞到VC_B應該是直截了當的。 您應該閱讀一些使用prepareForSegue:sender:示例prepareForSegue:sender: . 例如, 目標視圖控制器可能具有表示應顯示的屬性data 。 源視圖控制器必須在prepareForSegue:sender:設置此屬性。

通過VC_B將數據從VC_A傳遞到VC_C也應該是直截了當的。

注意:每個視圖控制器可以定制 (分離,修改,準備,切片,轉換等) data ,使其成為下一個視圖控制器的合適data

如果VC_C需要在其源視圖控制器VC_B中不可用的數據,那麼有幾種方法可以解決這個問題。 然而,這通常是糟糕設計的標誌。

可以擁有一個全局的應用程序模型。 假設,您的“應用程序模型”是Document類型的對象。 假設,在任何時候只有該應用程序模型的一個實例。 然後,該模型是一個“單例”, 可以從您的應用程序中的任何位置訪問,如下所示:

Document* document = [Document sharedDocument];

但是,獲取模型實例的首選方法是在第一個需要訪問它的視圖控制器中,在這種情況下:VC_A。

然後,VC_A將Document實例傳遞給下一個視圖控制器VC_B。 VC_B將文檔對像傳遞給VC_C。

您應該閱讀官方文檔“ View Controller Programming Guide for iOS ”。

例1

假設您有一個“用戶”列表。 該列表應顯示在表視圖控制器中,還應該有一個詳細視圖,顯示一個用戶的詳細信息。

表視圖控制器將具有“data”屬性users

UsersTableViewController.h中

@interface UsersTableViewController : UIViewController
@property (nonatomic, readonly) NSArray* users;
@end

(嚴格地說,此user屬性不需要是公共的。例如,如果表視圖在內部獲取用戶自己的列表,則無需從外部訪問它。

“users”數組是表視圖的數據 ,應以行的形式顯示。 每行顯示用戶的“摘要”。

應在詳細視圖控制器中顯示用戶的更多詳細信息。 詳細視圖控制器的數據是User類型的單個用戶。

當用戶在表視圖中選中某一行時,將顯示詳細視圖控制器。 在顯示之前,表視圖控制器必須配置詳細視圖控制器:表視圖控制器為當前所選用戶分配詳細視圖控制器的“數據屬性”。 因此,詳細視圖控制器應該具有公共屬性user

@interface UserViewController : UIViewController
@property (nonatomic) User* user;
@end

表視圖控制器在prepareForSegue:sender:配置詳細視圖控制器:

UsersTableViewController.m中

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"ShowUserDetails"]) {
        UserViewController* userViewController = [segue destinationViewController];
        userViewController.user = [self.users objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
    }
}

例2

第二個例子更複雜,並使用“委託”作為在控制器之間建立通信的手段。

警告:

這不是一個完整的例子。 本示例的目的是演示如何使用“委派”。 如示例所示,數據任務的全功能實現將需要更多的努力。 在這樣的場景中,“委託”將是實現這一目標的最優選方法(恕我直言)。

假設我們想要

  • 顯示用戶
  • 修改(編輯)用戶
  • 創建新用戶,和
  • 刪除用戶

從詳細視圖中。

這些“數據任務”不應由詳細視圖控制器本身執行 ,而是委託負責這些數據任務。

這些數據操作應由代表處理:

@protocol UserDataSourceDelegateProtocol <NSObject>
- (User*) viewControllerUser:(UserViewControllerBase*)viewController;
- (void) viewController:(UserViewControllerBase*)viewController dismissWithUpdatedUser:(User*)user;
- (void) viewController:(UserViewControllerBase*)viewController dismissWithDeletedUser:(User*)user;
- (void) viewController:(UserViewControllerBase*)viewController dismissWithCreatedUser:(User*)user;
@end

該協議反映了基本的CRUD方法(創建,讀取,更新,刪除)。

同樣,我們不希望Detail View Controller 本身執行這些數據方法,而是由實現UserDataSourceDelegateProtocol的實例執行。 詳細視圖控制器具有此委託的屬性,並將這些“數據任務”發送給委託。

可能有幾個詳細視圖控制器,抽像類UserViewControllerBase所有子類,它們處理顯示編輯創建任務。 可以在表視圖和“顯示用戶”視圖控制器中執行用戶刪除:

  • ShowUserViewController
  • EditUserViewController
  • NewUserViewController

例如, EditUserViewController將發送viewController:dismissWithUpdatedUser:當用戶viewController:dismissWithUpdatedUser: “後退”按鈕並且用戶已修改用戶對象時。 現在,代表可能允許也可能不允許關閉詳細視圖。 例如,當存在驗證錯誤時,它可能會禁止它。

UserDataSourceDelegateProtocol協議可以在根視圖控制器中實現,例如表視圖控制器。 但是,一個單獨的類,其唯一的責任是處理數據任務可能更合適。 在下面的示例中,表視圖控制器也將是此數據處理程序。

UserDataSourceDelegateProtocol可以在額外的頭中定義。

UsersTableViewController.m中

#import "UserDataSourceDelegateProtocol.h"
#import "ShowUserViewController.h"


@interface UsersTableViewController () <UserDataSourceDelegateProtocol> 
@property (nonatomic, readonly) NSArray* users;
@end


// This delegate will be called when the detail view controller request 
// the user object which shall be displayed.
- (User*) viewControllerUser:(UserViewControllerBase*)viewController {
    return [self.users objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
}

這裡,Table View Controller配置Show User Detail View Controller:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:UserShowSegueID])
    {
        ShowUserViewController* showViewController = segue.destinationViewController;
        showViewController.delegate = self; // Data Source Handler is self
    }
}

“編輯用戶”視圖控制器通常是“顯示用戶”視圖控制器的目標視圖控制器,當用戶選中“編輯”按鈕時,該控制器將被查看。

“顯示用戶”視圖控制器將為“編輯用戶”視圖控制器設置委託獲取相同的委託:

ShowUserViewController.m中

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:UserEditSegueID])
    {
        EditUserViewController* editViewController = segue.destinationViewController;
        editViewController.delegate = self.delegate; // pass through the data source hanlder
    }
}

數據委託可以處理更新的用戶,如下所示:

UsersTableViewController.m中

- (void) viewController:(UserViewControllerBase*)viewController
 dismissWithUpdatedUser:(User*)user {
    if (/* is valid user and can be saved */) {
        [viewController.presentingViewController dismissViewControllerAnimated:YES
                                                                     completion:nil];
    }
}




ios ios6 slcomposeviewcontroller social-framework