24、iOS开发:Facebook与AirPlay功能全解析

iOS开发:Facebook与AirPlay功能全解析

1. Facebook功能集成

在iOS开发中集成Facebook功能,首先要确保Native iOS App部分的Bundle ID与iOS应用info.plist中的Bundle ID相匹配。

1.1 Facebook权限体系

Facebook采用分层权限系统来访问和发布数据。若要获取如发布内容这样的高级权限,需先获得读取等低级权限。
- 基本权限请求 :首先要请求的是通用的个人资料读取权限,这能让应用读取用户的基本信息,如姓名、电子邮件和好友列表。读取墙贴需要额外权限,发布内容则需要更多权限。基本读取权限需先获授权,才能请求额外权限,不能将所有权限组合在一次调用中。例如,要发布到用户的时间线,需分两次请求权限。
以下是请求基本权限的代码示例:

ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *facebookAccountType = [accountStore 
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

NSDictionary *options = @{
    ACFacebookAudienceKey : ACFacebookAudienceEveryone,
    ACFacebookAppIdKey : @"165243936994502",
    ACFacebookPermissionsKey : @[@"email"]
};

[accountStore requestAccessToAccountsWithType:facebookAccountType options:options  
completion:^(BOOL granted, NSError *error){}];
  • 扩展权限请求 :基本权限授予后,可响应于用户授予基本权限的操作,请求发布到信息流的权限。代码示例如下:
[accountStore requestAccessToAccountsWithType:facebookAccountType options:options  
completion:^(BOOL granted, NSError *error)
{
    if (granted)
    {
        NSLog(@"Basic access granted");

        NSDictionary *secondOptions = @{
            ACFacebookAudienceKey : ACFacebookAudienceEveryone,
            ACFacebookAppIdKey : @"165243936994502",
            ACFacebookPermissionsKey :  @[@"publish_stream"]
        };

        [accountStore requestAccessToAccountsWithType:facebookAccountType options:secondOptions
        completion:^(BOOL granted, NSError *error)
        {
            if (granted)
            {
                NSLog(@"Extended access granted");

                NSArray *accounts = [accountStore accountsWithAccountType:facebookAccountType];
                self.facebookAccount = [accounts lastObject];

                [self performSelectorOnMainThread:@selector(postFromFacebook) withObject:nil
                waitUntilDone:NO];
            }
            else
            {
                [self performSelectorOnMainThread:@selector(displayAlertWithString:) 
                withObject:error
                waitUntilDone:NO];
            }
        }];
    }
    else
    {
        NSLog(@"Basic access denied: %@", [error localizedDescription]);
    }
}];
1.2 自定义Facebook帖子

获得发布到用户信息流的权限后,即可进行自定义帖子发布。使用Accounts框架,在用户授权的情况下,可通过自定义界面甚至无界面发布内容。
- 设置请求URL :根据状态更新是否包含媒体(如图像或视频),Facebook需要不同的Feed URL。若状态更新不包含图像,URL应设为 https://graph.facebook.com/me/feed ;否则,URL需设为 https://graph.facebook.com/me/photos

BOOL attachedImage = YES;
NSURL *feedURL = nil;

if(attachedImage)
{
    feedURL = [NSURL URLWithString:
    @"https://graph.facebook.com/me/photos"];
}
else
{
    feedURL = [NSURL URLWithString:
    @"https://graph.facebook.com/me/feed"];
}
  • 设置消息文本 :在参数字典中设置消息文本,创建名为 message 的键,并将其值设为要发布的文本。
NSDictionary *parameters = [NSDictionary dictionaryWithObject:[NSString stringWithFormat: @"I just 
abducted %0.0f cow(s) in UFOs for iPhone!", score] forKey:@"message"];
  • 创建SLRequest对象 :创建一个 SLRequest 对象,包含与Facebook API交互所需的所有信息。
SLRequest *feedRequest = [SLRequest
    requestForServiceType:SLServiceTypeFacebook
    requestMethod:SLRequestMethodPOST
    URL:feedURL
    parameters:parameters];
  • 添加附件 :若状态更新包含附加图像文件,需将图像数据转换为 NSData ,并通过 addMultipartData: 方法添加到 SLRequest 中。
if(attachedImage)
{
    NSData *imageData = UIImagePNGRepresentation([UIImage
    imageNamed:@"Saucer1.png"]);

    [feedRequest addMultipartData:imageData
    withName:@"source" type:@"multipart/form-data"
    filename:@"Image"];
}
  • 设置账户并发送请求 :将 SLRequest account 属性设置为之前认证的账户,然后调用 performRequestWithHandler 方法将请求发送到Facebook服务器。
feedRequest.account = self.facebookAccount;

[feedRequest performRequestWithHandler:^(NSData *responseData,
    NSHTTPURLResponse *urlResponse, NSError *error)
{
    NSLog(@"Facebook post statusCode: %u", [urlResponse statusCode]);
    if([urlResponse statusCode] == 200)
    {
        [self performSelectorOnMainThread:@selector(displayAlertWithString:) withObject:@"Your
        message has been posted to Facebook" waitUntilDone:NO];
    }
    else if(error != nil)
    {
        [self performSelectorOnMainThread:@selector(displayAlertWithString:) withObject:error
        waitUntilDone:NO];
    }
}];
1.3 进一步使用Facebook API

Facebook API功能丰富且更新频繁,可利用 SLRequest 与之交互。例如,若要获取用户的信息流,可按以下方式实现:

NSURL *feedURL = [NSURL URLWithString:@"https://graph.facebook.com/me/feed"];

SLRequest *feedRequest = [SLRequest
    requestForServiceType:SLServiceTypeFacebook
    requestMethod:SLRequestMethodGET
    URL:feedURL
    parameters:nil];

feedRequest.account = self.facebookAccount;

[feedRequest performRequestWithHandler:^(NSData *responseData,
    NSHTTPURLResponse *urlResponse, NSError *error)
{
    NSLog(@"Facebook post statusCode: %u", [urlResponse statusCode]);
    if([urlResponse statusCode] == 200)
    {
        NSLog(@"Facebook Timeline: [[NSJSONSerialization JSONObjectWithData:responseData
        options:NSJSONReadingMutableLeaves error:&error] objectForKey:@"data"]);
    }
}];
2. AirPlay功能应用

AirPlay于iOS 4.3引入,在iOS 5.0中得到大幅增强,可将音频或视觉信息共享到兼容设备,常见的如Apple TV用于视频和音频播放,支持AirPlay的音响系统用于音乐播放。

2.1 内置播放器的AirPlay支持

有三个类原生支持AirPlay输出: AVPlayer MPMoviePlayerController UIWebView 。播放媒体内容时,AirPlay默认开启,但出于版权等原因,可能需修改此默认行为。
- AVPlayer 对象有 allowsAirPlayVideo 属性,接受布尔值以确定是否显示AirPlay输出控件。
- MPMoviePlayerController 类有类似的 allowsAirPlay 属性。
- UIWebView 使用 mediaPlaybackAllowsAirPlay 属性。禁用或启用 UIWebView 中的AirPlay时,需注意内容可能会专门禁用AirPlay。
需注意,AirPlay在iOS模拟器中无法使用,且AirPlay控件仅在有本地AirPlay设备(如Apple TV)时才会显示。

2.2 MPNowPlayingInfoCenter的使用

许多支持AirPlay的音响系统支持显示当前播放项目的元数据,如歌曲名称和艺术家信息。可使用 MPNowPlayingInfoCenter 类设置这些元数据。

MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];

NSDictionary *songInfo = [NSDictionary dictionaryWithObjectsAndKeys:
    @"Counting Crows", MPMediaItemPropertyArtist,
    @"Rain King", MPMediaItemPropertyTitle,
    @"August and Everything After", MPMediaItemPropertyAlbumTitle, nil
];

center.nowPlayingInfo = songInfo;

以下是 MPNowPlayingInfoCenter 设置元数据时可用的常量及说明:
| 常量 | 描述 |
| — | — |
| MPMediaItemPropertyAlbumTitle | 表示专辑名称的NSString |
| MPMediaItemPropertyAlbumTrackCount | 表示总曲目数的NSNumber |
| MPMediaItemPropertyAlbumTrackNumber | 表示当前曲目编号的NSNumber |
| MPMediaItemPropertyArtist | 表示艺术家姓名的NSString |
| MPMediaItemPropertyArtwork | 表示正在播放项目的艺术作品的MPMediaItemArtwork实例 |
| MPMediaItemPropertyComposer | 表示作曲家姓名的NSString |
| MPMediaItemPropertyDiscCount | 表示总光盘数的NSNumber |
| MPMediaItemPropertyDiscNumber | 表示当前光盘编号的NSNumber |
| MPMediaItemPropertyGenre | 表示流派名称的NSString |
| MPMediaItemPropertyPersistentID | 表示正在播放项目的NSNumber,此标识符在应用启动期间保持不变,但在同步时可能会重置 |
| MPMediaItemPropertyPlaybackDuration | 表示当前播放持续时间(以秒为单位)的NSNumber |
| MPMediaItemPropertyTitle | 表示正在播放项目的名称的NSString,如文件名 |

2.3 响应远程事件

当AirPlay播放媒体时,处理媒体输出的设备可能接受用户输入,如切换曲目、暂停、跳过或快进。应用需响应并正确处理这些事件。
- 开启事件接收 :调用 UIApplication 单例的 beginReceivingRemoteControlEvents 方法,让操作系统知道应用对接收这些通知感兴趣。

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  • 关闭事件接收 :不再需要接收通知时,调用 endReceivingRemoteControlEvents 方法。
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
  • 事件处理示例 :当事件发生时,会调用 remoteControlReceivedWithEvent: 方法。以下是处理部分事件的示例:
- (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent
{
    if (receivedEvent.type == UIEventTypeRemoteControl)
    {
        switch (receivedEvent.subtype)
        {
            case UIEventSubtypeRemoteControlPlay:
                [self play];
                break;

            case UIEventSubtypeRemoteControlPause:
                [self pause];
                break;

            case UIEventSubtypeRemoteControlNextTrack:
                [self nextTrack];
                break;

            case UIEventSubtypeRemoteControlPreviousTrack:
                [self previousTrack];
                break;
        }
    }
}
2.4 在应用中启用AirPlay

若应用未使用支持AirPlay的三个类,可使用 MPVolumeView 类向用户展示AirPlay选项。以下代码示例隐藏了音量滑块条,仅显示设备选择器:

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:
CGRectMake(15, 15, 0, 0)];

[volumeView setShowsVolumeSlider:NO];
[self.view addSubview: volumeView];
[volumeView release];

使用AirPlay类时,应用需先导入所需的媒体播放器头文件 #import <MediaPlayer/MediaPlayer.h> ,并添加 MediaPlayer.Framework 。系统声音(如键盘点击声和警报声)不会通过AirPlay扬声器播放,若应用大量使用系统声音,应将其作为应用的常规音频播放,以便通过AirPlay发送。

2.5 AirPlay镜像

自iOS 7起,应用无法自行启用AirPlay镜像,需使用系统工具。在iOS 7中,从屏幕底部向上滑动调出控制中心,选择AirPlay按钮。若设备支持AirPlay镜像(如Apple TV),会出现切换开关以启用它。iOS 6用户需双击主屏幕按钮,在快速应用切换器中向左滑动到播放控制界面,再向右滑动以调出AirPlay控件,从而开启AirPlay镜像。

2.6 第二屏幕的AirPlay应用

应用可在iOS设备和AirPlay设备上显示不同内容。用户需按上述方法开启AirPlay监控,应用即可为每个屏幕显示完全不同的内容。
- 检测第二屏幕 :使用以下代码检测第二屏幕是否可用:

if ([[UIScreen screens] count] > 1)
  • 设置第二屏幕窗口 :若检测到第二屏幕,需设置对第二屏幕的引用并创建新窗口。
UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
CGRect screenBounds = secondScreen.bounds;
UIWindow * secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
secondWindow.screen = secondScreen;
secondWindow.hidden = NO;
  • 示例代码 :以UFO游戏为例,修改 playButtonPressed 方法,添加检测和设置第二屏幕的方法 checkForExistingScreenAndInitializeIfPresent
-(IBAction)playButtonPressed
{
    if([self checkForExistingScreenAndInitializeIfPresent])
    {
        //Using second screen
    }
    else
    {
        gameViewController = [[UFOGameViewController alloc]  init];
        gameViewController.gcManager = gcManager;
        [self.navigationController pushViewController: gameViewController animated:YES];
    }
}

- (bool)checkForExistingScreenAndInitializeIfPresent
{
    if ([[UIScreen screens] count] > 1)
    {
        UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
        CGRect screenBounds = secondScreen.bounds;
        UIWindow * secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        secondWindow.screen = secondScreen;

        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [button addTarget:self action:@selector(fire)
        forControlEvents:UIControlEventTouchDown];

        [button addTarget:self action:@selector(fireStop)
        forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];

        [button setTitle:@"Fire!" forState:UIControlStateNormal];
        button.frame = CGRectMake(80.0, 180.0, 160.0, 40.0);
        [self.view addSubview:button];

        secondWindow.hidden = NO;

        gameViewController = [[UFOGameViewController alloc] init];
        gameViewController.view.frame = screenBounds;
        gameViewController.gcManager = gcManager;
        [secondWindow addSubview:gameViewController.view];

        return YES;
    }
    return NO;
}

要记住,Apple TV的显示屏尺寸可能与预期不同,应用元素需能检测其显示范围并相应缩放。

iOS开发:Facebook与AirPlay功能全解析

3. 总结与注意事项
3.1 Facebook功能总结
  • 权限请求 :Facebook采用分层权限系统,基本读取权限需先获授权,才能请求额外权限。请求基本权限时,需配置参数并调用 requestAccessToAccountsWithType:options:completion: 方法;请求扩展权限时,在基本权限授予后进行。
  • 自定义帖子 :获得发布权限后,可使用Accounts框架进行自定义帖子发布。需根据状态更新是否包含媒体设置不同的Feed URL,创建 SLRequest 对象并设置相关参数,最后发送请求到Facebook服务器。
  • API使用 :利用 SLRequest 可与Facebook API进行交互,实现如获取用户信息流等功能。
3.2 AirPlay功能总结
  • 内置播放器支持 AVPlayer MPMoviePlayerController UIWebView 原生支持AirPlay输出,可通过相应属性修改默认行为。
  • 元数据设置 :使用 MPNowPlayingInfoCenter 类可设置支持AirPlay的音响系统显示的元数据。
  • 远程事件响应 :应用需开启和关闭事件接收,并在 remoteControlReceivedWithEvent: 方法中处理远程事件。
  • 启用AirPlay :未使用支持类时,可使用 MPVolumeView 类展示AirPlay选项。
  • 镜像与第二屏幕 :iOS 7及以上需使用系统工具启用AirPlay镜像;应用可检测并为第二屏幕显示不同内容。
3.3 注意事项
  • Facebook :开发时需将示例中的Facebook ID替换为自己应用的ID;进行自定义状态更新时,要包含 Accounts.framework 并导入 accounts/Accounts.h
  • AirPlay :AirPlay在iOS模拟器中无法使用,且系统声音需作为应用常规音频播放才能通过AirPlay发送;使用AirPlay类需导入相关头文件和框架。
4. 操作流程梳理
4.1 Facebook自定义帖子发布流程
graph TD;
    A[请求基本权限] --> B{权限是否授予};
    B -- 是 --> C[请求扩展权限];
    B -- 否 --> D[提示基本权限拒绝];
    C --> E{扩展权限是否授予};
    E -- 是 --> F[设置请求URL];
    E -- 否 --> G[提示扩展权限拒绝];
    F --> H[设置消息文本];
    H --> I[创建SLRequest对象];
    I --> J{是否有附件};
    J -- 是 --> K[添加附件];
    J -- 否 --> L[跳过添加附件];
    K --> M[设置账户并发送请求];
    L --> M;
    M --> N{请求是否成功};
    N -- 是 --> O[提示发布成功];
    N -- 否 --> P[提示发布失败];
4.2 AirPlay第二屏幕使用流程
graph TD;
    A[检测第二屏幕] --> B{是否存在第二屏幕};
    B -- 是 --> C[设置第二屏幕窗口];
    B -- 否 --> D[使用单屏幕模式];
    C --> E[创建相关按钮和视图];
    E --> F[显示第二屏幕内容];
5. 常见问题解答
问题 解答
Facebook权限请求失败怎么办? 检查Facebook ID是否正确,网络连接是否正常,以及用户是否拒绝了权限请求。
AirPlay在模拟器中无法使用怎么办? AirPlay在iOS模拟器中本身不支持,需在真机上测试。
自定义Facebook帖子发布失败,状态码非200怎么办? 检查请求URL是否正确,参数设置是否有误,以及网络连接是否正常。
AirPlay设备选择器不显示怎么办? 确保有本地AirPlay设备(如Apple TV)可用,且应用已正确导入相关头文件和框架。

通过以上对Facebook和AirPlay功能的详细介绍,开发者可以在iOS应用中更灵活地集成这些功能,为用户带来更好的体验。无论是社交分享还是多媒体播放,这些功能都能为应用增色不少。在实际开发中,要注意各个功能的细节和注意事项,遇到问题可参考常见问题解答进行排查。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值