- Add Facebook SDK
- Add PNUser Login
This commit is contained in:
1 parent
f2885301b9
commit
a6dcf672bb
370 files changed
+44655
-2705
No files matched your search
+101
@@ -0,0 +1,101 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKAppGroupContent.h>
|
||||
|
||||
@protocol FBSDKAppGroupAddDialogDelegate;
|
||||
|
||||
/*!
|
||||
@abstract A dialog for creating app groups.
|
||||
*/
|
||||
@interface FBSDKAppGroupAddDialog : NSObject
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build up an app group dialog with content and a delegate.
|
||||
@param content The content for the app group.
|
||||
@param delegate The receiver's delegate.
|
||||
*/
|
||||
+ (instancetype)showWithContent:(FBSDKAppGroupContent *)content
|
||||
delegate:(id<FBSDKAppGroupAddDialogDelegate>)delegate;
|
||||
|
||||
/*!
|
||||
@abstract The receiver's delegate or nil if it doesn't have a delegate.
|
||||
*/
|
||||
@property (nonatomic, weak) id<FBSDKAppGroupAddDialogDelegate> delegate;
|
||||
|
||||
/*!
|
||||
@abstract The content for app group.
|
||||
*/
|
||||
@property (nonatomic, copy) FBSDKAppGroupContent *content;
|
||||
|
||||
/*!
|
||||
@abstract A Boolean value that indicates whether the receiver can initiate an app group dialog.
|
||||
@discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is
|
||||
required but not available. This method does not validate the content on the receiver, so this can be checked before
|
||||
building up the content.
|
||||
@see validateWithError:
|
||||
@result YES if the receiver can share, otherwise NO.
|
||||
*/
|
||||
- (BOOL)canShow;
|
||||
|
||||
/*!
|
||||
@abstract Begins the app group dialog from the receiver.
|
||||
@result YES if the receiver was able to show the dialog, otherwise NO.
|
||||
*/
|
||||
- (BOOL)show;
|
||||
|
||||
/*!
|
||||
@abstract Validates the content on the receiver.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@return YES if the content is valid, otherwise NO.
|
||||
*/
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract A delegate for FBSDKAppGroupAddDialog.
|
||||
@discussion The delegate is notified with the results of the app group request as long as the application has
|
||||
permissions to receive the information. For example, if the person is not signed into the containing app, the shower
|
||||
may not be able to distinguish between completion of an app group request and cancellation.
|
||||
*/
|
||||
@protocol FBSDKAppGroupAddDialogDelegate <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app group request completes without error.
|
||||
@param appGroupAddDialog The FBSDKAppGroupAddDialog that completed.
|
||||
@param results The results from the dialog. This may be nil or empty.
|
||||
*/
|
||||
- (void)appGroupAddDialog:(FBSDKAppGroupAddDialog *)appGroupAddDialog didCompleteWithResults:(NSDictionary *)results;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app group request encounters an error.
|
||||
@param appGroupAddDialog The FBSDKAppGroupAddDialog that completed.
|
||||
@param error The error.
|
||||
*/
|
||||
- (void)appGroupAddDialog:(FBSDKAppGroupAddDialog *)appGroupAddDialog didFailWithError:(NSError *)error;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app group dialog is cancelled.
|
||||
@param appGroupAddDialog The FBSDKAppGroupAddDialog that completed.
|
||||
*/
|
||||
- (void)appGroupAddDialogDidCancel:(FBSDKAppGroupAddDialog *)appGroupAddDialog;
|
||||
|
||||
@end
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKAppGroupAddDialog.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
@interface FBSDKAppGroupAddDialog () <FBSDKWebDialogDelegate>
|
||||
@end
|
||||
|
||||
@implementation FBSDKAppGroupAddDialog
|
||||
{
|
||||
FBSDKWebDialog *_webDialog;
|
||||
}
|
||||
|
||||
#define FBSDK_APP_GROUP_CREATE_METHOD_NAME @"game_group_create"
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (instancetype)showWithContent:(FBSDKAppGroupContent *)content
|
||||
delegate:(id<FBSDKAppGroupAddDialogDelegate>)delegate
|
||||
{
|
||||
FBSDKAppGroupAddDialog *dialog = [[self alloc] init];
|
||||
dialog.content = content;
|
||||
dialog.delegate = delegate;
|
||||
[dialog show];
|
||||
return dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_webDialog = [[FBSDKWebDialog alloc] init];
|
||||
_webDialog.delegate = self;
|
||||
_webDialog.name = FBSDK_APP_GROUP_CREATE_METHOD_NAME;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_webDialog.delegate = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canShow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)show
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canShow]) {
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"App group create dialog is not available."];
|
||||
[_delegate appGroupAddDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self validateWithError:&error]) {
|
||||
[_delegate appGroupAddDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
|
||||
FBSDKAppGroupContent *content = self.content;
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.name forKey:@"name"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.groupDescription forKey:@"description"];
|
||||
[FBSDKInternalUtility dictionary:parameters
|
||||
setObject:NSStringFromFBSDKAppGroupPrivacy(content.privacy)
|
||||
forKey:@"privacy"];
|
||||
|
||||
_webDialog.parameters = parameters;
|
||||
[_webDialog show];
|
||||
[FBSDKInternalUtility registerTransientObject:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
FBSDKAppGroupContent *content = self.content;
|
||||
if (!content) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"content" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (![content.name length]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"name" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (![content.groupDescription length]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"groupDescription" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKWebDialogDelegate
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
NSError *error = [FBSDKShareError errorWithCode:[FBSDKTypeUtility unsignedIntegerValue:results[@"error_code"]]
|
||||
message:[FBSDKTypeUtility stringValue:results[@"error_message"]]];
|
||||
[self _handleCompletionWithDialogResults:results error:error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[self _handleCompletionWithDialogResults:nil error:error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[_delegate appGroupAddDialogDidCancel:self];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error
|
||||
{
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
switch (error.code) {
|
||||
case 0:{
|
||||
[_delegate appGroupAddDialog:self didCompleteWithResults:results];
|
||||
break;
|
||||
}
|
||||
case 4201:{
|
||||
[_delegate appGroupAddDialogDidCancel:self];
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
[_delegate appGroupAddDialog:self didFailWithError:error];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM(NSUInteger, FBSDKAppGroupPrivacy)
|
||||
@abstract Specifies the privacy of a group.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKAppGroupPrivacy)
|
||||
{
|
||||
/*! Anyone can see the group, who's in it and what members post. */
|
||||
FBSDKAppGroupPrivacyOpen = 0,
|
||||
/*! Anyone can see the group and who's in it, but only members can see posts. */
|
||||
FBSDKAppGroupPrivacyClosed,
|
||||
};
|
||||
|
||||
/*!
|
||||
@abstract Converts an FBSDKAppGroupPrivacy to an NSString.
|
||||
*/
|
||||
FBSDK_EXTERN NSString *NSStringFromFBSDKAppGroupPrivacy(FBSDKAppGroupPrivacy privacy);
|
||||
|
||||
/*!
|
||||
@abstract A model for creating an app group.
|
||||
*/
|
||||
@interface FBSDKAppGroupContent : NSObject <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract The description of the group.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *groupDescription;
|
||||
|
||||
/*!
|
||||
@abstract The name of the group.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *name;
|
||||
|
||||
/*!
|
||||
@abstract The privacy for the group.
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKAppGroupPrivacy privacy;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another app group content.
|
||||
@param content The other content
|
||||
@return YES if the receiver's values are equal to the other content's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToAppGroupContent:(FBSDKAppGroupContent *)content;
|
||||
|
||||
@end
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKAppGroupContent.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#define FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY @"groupDescription"
|
||||
#define FBSDK_APP_GROUP_CONTENT_NAME_KEY @"name"
|
||||
#define FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY @"privacy"
|
||||
|
||||
NSString *NSStringFromFBSDKAppGroupPrivacy(FBSDKAppGroupPrivacy privacy)
|
||||
{
|
||||
switch (privacy) {
|
||||
case FBSDKAppGroupPrivacyClosed:{
|
||||
return @"closed";
|
||||
}
|
||||
case FBSDKAppGroupPrivacyOpen:{
|
||||
return @"open";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@implementation FBSDKAppGroupContent
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[_groupDescription hash],
|
||||
[_name hash],
|
||||
_privacy,
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKAppGroupContent class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToAppGroupContent:(FBSDKAppGroupContent *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToAppGroupContent:(FBSDKAppGroupContent *)content
|
||||
{
|
||||
return (content &&
|
||||
(_privacy == content.privacy) &&
|
||||
[FBSDKInternalUtility object:_name isEqualToObject:content.name] &&
|
||||
[FBSDKInternalUtility object:_groupDescription isEqualToObject:content.groupDescription]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_groupDescription = [decoder decodeObjectOfClass:[NSString class]
|
||||
forKey:FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY];
|
||||
_name = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY];
|
||||
_privacy = [decoder decodeIntegerForKey:FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_groupDescription forKey:FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY];
|
||||
[encoder encodeObject:_name forKey:FBSDK_APP_GROUP_CONTENT_NAME_KEY];
|
||||
[encoder encodeInteger:_privacy forKey:FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKAppGroupContent *copy = [[FBSDKAppGroupContent alloc] init];
|
||||
copy->_groupDescription = [_groupDescription copy];
|
||||
copy->_name = [_name copy];
|
||||
copy->_privacy = _privacy;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol FBSDKAppGroupJoinDialogDelegate;
|
||||
|
||||
/*!
|
||||
@abstract A dialog for joining app groups.
|
||||
*/
|
||||
@interface FBSDKAppGroupJoinDialog : NSObject
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build up an app group dialog with content and a delegate.
|
||||
@param groupID The ID for the group.
|
||||
@param delegate The receiver's delegate.
|
||||
*/
|
||||
+ (instancetype)showWithGroupID:(NSString *)groupID
|
||||
delegate:(id<FBSDKAppGroupJoinDialogDelegate>)delegate;
|
||||
|
||||
/*!
|
||||
@abstract The receiver's delegate or nil if it doesn't have a delegate.
|
||||
*/
|
||||
@property (nonatomic, weak) id<FBSDKAppGroupJoinDialogDelegate> delegate;
|
||||
|
||||
/*!
|
||||
@abstract The ID for group.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *groupID;
|
||||
|
||||
/*!
|
||||
@abstract A Boolean value that indicates whether the receiver can initiate an app group dialog.
|
||||
@discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is
|
||||
required but not available. This method does not validate the content on the receiver, so this can be checked before
|
||||
building up the content.
|
||||
@see validateWithError:
|
||||
@result YES if the receiver can share, otherwise NO.
|
||||
*/
|
||||
- (BOOL)canShow;
|
||||
|
||||
/*!
|
||||
@abstract Begins the app group dialog from the receiver.
|
||||
@result YES if the receiver was able to show the dialog, otherwise NO.
|
||||
*/
|
||||
- (BOOL)show;
|
||||
|
||||
/*!
|
||||
@abstract Validates the content on the receiver.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@return YES if the content is valid, otherwise NO.
|
||||
*/
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract A delegate for FBSDKAppGroupJoinDialog.
|
||||
@discussion The delegate is notified with the results of the app group request as long as the application has
|
||||
permissions to receive the information. For example, if the person is not signed into the containing app, the shower
|
||||
may not be able to distinguish between completion of an app group request and cancellation.
|
||||
*/
|
||||
@protocol FBSDKAppGroupJoinDialogDelegate <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app group request completes without error.
|
||||
@param appGroupJoinDialog The FBSDKAppGroupJoinDialog that completed.
|
||||
@param results The results from the dialog. This may be nil or empty.
|
||||
*/
|
||||
- (void)appGroupJoinDialog:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog didCompleteWithResults:(NSDictionary *)results;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app group request encounters an error.
|
||||
@param appGroupJoinDialog The FBSDKAppGroupJoinDialog that completed.
|
||||
@param error The error.
|
||||
*/
|
||||
- (void)appGroupJoinDialog:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog didFailWithError:(NSError *)error;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app group dialog is cancelled.
|
||||
@param appGroupJoinDialog The FBSDKAppGroupJoinDialog that completed.
|
||||
*/
|
||||
- (void)appGroupJoinDialogDidCancel:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog;
|
||||
|
||||
@end
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKAppGroupJoinDialog.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
@interface FBSDKAppGroupJoinDialog () <FBSDKWebDialogDelegate>
|
||||
@end
|
||||
|
||||
@implementation FBSDKAppGroupJoinDialog
|
||||
{
|
||||
FBSDKWebDialog *_webDialog;
|
||||
}
|
||||
|
||||
#define FBSDK_APP_GROUP_JOIN_METHOD_NAME @"game_group_join"
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (instancetype)showWithGroupID:(NSString *)groupID
|
||||
delegate:(id<FBSDKAppGroupJoinDialogDelegate>)delegate
|
||||
{
|
||||
FBSDKAppGroupJoinDialog *dialog = [[self alloc] init];
|
||||
dialog.groupID = groupID;
|
||||
dialog.delegate = delegate;
|
||||
[dialog show];
|
||||
return dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_webDialog = [[FBSDKWebDialog alloc] init];
|
||||
_webDialog.delegate = self;
|
||||
_webDialog.name = FBSDK_APP_GROUP_JOIN_METHOD_NAME;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_webDialog.delegate = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canShow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)show
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canShow]) {
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"App group join dialog is not available."];
|
||||
[_delegate appGroupJoinDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self validateWithError:&error]) {
|
||||
[_delegate appGroupJoinDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:self.groupID forKey:@"id"];
|
||||
|
||||
_webDialog.parameters = parameters;
|
||||
[_webDialog show];
|
||||
[FBSDKInternalUtility registerTransientObject:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (![self.groupID length]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"groupID" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKWebDialogDelegate
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
NSError *error = [FBSDKShareError errorWithCode:[FBSDKTypeUtility unsignedIntegerValue:results[@"error_code"]]
|
||||
message:[FBSDKTypeUtility stringValue:results[@"error_message"]]];
|
||||
[self _handleCompletionWithDialogResults:results error:error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[self _handleCompletionWithDialogResults:nil error:error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[_delegate appGroupJoinDialogDidCancel:self];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error
|
||||
{
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
switch (error.code) {
|
||||
case 0:{
|
||||
[_delegate appGroupJoinDialog:self didCompleteWithResults:results];
|
||||
break;
|
||||
}
|
||||
case 4201:{
|
||||
[_delegate appGroupJoinDialogDidCancel:self];
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
[_delegate appGroupJoinDialog:self didFailWithError:error];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
/*!
|
||||
@abstract A model for app invite.
|
||||
*/
|
||||
@interface FBSDKAppInviteContent : NSObject <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract A URL to a preview image that will be displayed with the app invite
|
||||
|
||||
@discussion This is optional. If you don't include it a fallback image will be used.
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL *appInvitePreviewImageURL;
|
||||
|
||||
/*!
|
||||
@abstract An app link target that will be used as a target when the user accept the invite.
|
||||
|
||||
@discussion This is a requirement.
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL *appLinkURL;
|
||||
|
||||
/*!
|
||||
@deprecated Use `appInvitePreviewImageURL` instead.
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL *previewImageURL __attribute__ ((deprecated("use appInvitePreviewImageURL instead")));
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another app invite content.
|
||||
@param content The other content
|
||||
@return YES if the receiver's values are equal to the other content's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToAppInviteContent:(FBSDKAppInviteContent *)content;
|
||||
|
||||
@end
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKAppInviteContent.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
#define FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY @"appLinkURL"
|
||||
#define FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY @"previewImage"
|
||||
|
||||
@implementation FBSDKAppInviteContent
|
||||
|
||||
- (NSURL *)previewImageURL
|
||||
{
|
||||
return self.appInvitePreviewImageURL;
|
||||
}
|
||||
|
||||
- (void)setPreviewImageURL:(NSURL *)previewImageURL
|
||||
{
|
||||
self.appInvitePreviewImageURL = previewImageURL;
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[_appLinkURL hash],
|
||||
[_appInvitePreviewImageURL hash],
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKAppInviteContent class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToAppInviteContent:(FBSDKAppInviteContent *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToAppInviteContent:(FBSDKAppInviteContent *)content
|
||||
{
|
||||
return (content &&
|
||||
[FBSDKInternalUtility object:_appLinkURL isEqualToObject:content.appLinkURL] &&
|
||||
[FBSDKInternalUtility object:_appInvitePreviewImageURL isEqualToObject:content.appInvitePreviewImageURL]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_appLinkURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY];
|
||||
_appInvitePreviewImageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_appLinkURL forKey:FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY];
|
||||
[encoder encodeObject:_appInvitePreviewImageURL forKey:FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKAppInviteContent *copy = [[FBSDKAppInviteContent alloc] init];
|
||||
copy->_appLinkURL = [_appLinkURL copy];
|
||||
copy->_appInvitePreviewImageURL = [_appInvitePreviewImageURL copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKAppInviteContent.h>
|
||||
|
||||
@protocol FBSDKAppInviteDialogDelegate;
|
||||
|
||||
/*!
|
||||
@abstract A dialog for sending App Invites.
|
||||
*/
|
||||
@interface FBSDKAppInviteDialog : NSObject
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to show a FBSDKAppInviteDialog
|
||||
@param viewController A UIViewController to present the dialog from.
|
||||
@param content The content for the app invite.
|
||||
@param delegate The receiver's delegate.
|
||||
*/
|
||||
+ (instancetype)showFromViewController:(UIViewController *)viewController
|
||||
withContent:(FBSDKAppInviteContent *)content
|
||||
delegate:(id<FBSDKAppInviteDialogDelegate>)delegate;
|
||||
|
||||
|
||||
/*!
|
||||
@deprecated use showFromViewController:withContent:delegate: instead
|
||||
*/
|
||||
+ (instancetype)showWithContent:(FBSDKAppInviteContent *)content delegate:(id<FBSDKAppInviteDialogDelegate>)delegate
|
||||
__attribute__ ((deprecated("use showFromViewController:withContent:delegate: instead")));
|
||||
|
||||
/*!
|
||||
@abstract A UIViewController to present the dialog from.
|
||||
@discussion If not specified, the top most view controller will be automatically determined as best as possible.
|
||||
*/
|
||||
@property (nonatomic, weak) UIViewController *fromViewController;
|
||||
|
||||
/*!
|
||||
@abstract The receiver's delegate or nil if it doesn't have a delegate.
|
||||
*/
|
||||
@property (nonatomic, weak) id<FBSDKAppInviteDialogDelegate> delegate;
|
||||
|
||||
/*!
|
||||
@abstract The content for app invite.
|
||||
*/
|
||||
@property (nonatomic, copy) FBSDKAppInviteContent *content;
|
||||
|
||||
/*!
|
||||
@abstract A Boolean value that indicates whether the receiver can initiate an app invite.
|
||||
@discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is
|
||||
required but not available. This method does not validate the content on the receiver, so this can be checked before
|
||||
building up the content.
|
||||
@see validateWithError:
|
||||
@result YES if the receiver can show the dialog, otherwise NO.
|
||||
*/
|
||||
- (BOOL)canShow;
|
||||
|
||||
/*!
|
||||
@abstract Begins the app invite from the receiver.
|
||||
@result YES if the receiver was able to show the dialog, otherwise NO.
|
||||
*/
|
||||
- (BOOL)show;
|
||||
|
||||
/*!
|
||||
@abstract Validates the content on the receiver.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@return YES if the content is valid, otherwise NO.
|
||||
*/
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract A delegate for FBSDKAppInviteDialog.
|
||||
@discussion The delegate is notified with the results of the app invite as long as the application has permissions to
|
||||
receive the information. For example, if the person is not signed into the containing app, the shower may not be able
|
||||
to distinguish between completion of an app invite and cancellation.
|
||||
*/
|
||||
@protocol FBSDKAppInviteDialogDelegate <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app invite completes without error.
|
||||
@param appInviteDialog The FBSDKAppInviteDialog that completed.
|
||||
@param results The results from the dialog. This may be nil or empty.
|
||||
*/
|
||||
- (void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didCompleteWithResults:(NSDictionary *)results;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the app invite encounters an error.
|
||||
@param appInviteDialog The FBSDKAppInviteDialog that completed.
|
||||
@param error The error.
|
||||
*/
|
||||
- (void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didFailWithError:(NSError *)error;
|
||||
|
||||
@end
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKAppInviteDialog.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareDefines.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
@implementation FBSDKAppInviteDialog
|
||||
|
||||
#define FBSDK_APP_INVITE_METHOD_MIN_VERSION @"20140410"
|
||||
#define FBSDK_APP_INVITE_METHOD_NAME @"appinvites"
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if ([FBSDKAppInviteDialog class] == self) {
|
||||
[FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK];
|
||||
// ensure that we have updated the dialog configs if we haven't already
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
|
||||
+ (instancetype)showWithContent:(FBSDKAppInviteContent *)content delegate:(id<FBSDKAppInviteDialogDelegate>)delegate
|
||||
{
|
||||
return [self showFromViewController:nil withContent:content delegate:delegate];
|
||||
}
|
||||
|
||||
+ (instancetype)showFromViewController:(UIViewController *)viewController
|
||||
withContent:(FBSDKAppInviteContent *)content
|
||||
delegate:(id<FBSDKAppInviteDialogDelegate>)delegate;
|
||||
{
|
||||
FBSDKAppInviteDialog *appInvite = [[self alloc] init];
|
||||
appInvite.content = content;
|
||||
appInvite.delegate = delegate;
|
||||
appInvite.fromViewController = viewController;
|
||||
[appInvite show];
|
||||
return appInvite;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canShow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)show
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canShow]) {
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"App invite dialog is not available."];
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self validateWithError:&error]) {
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:self.content.appLinkURL forKey:@"app_link_url"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:self.content.appInvitePreviewImageURL forKey:@"preview_image_url"];
|
||||
FBSDKBridgeAPIRequest *webBridgeRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb
|
||||
scheme:FBSDK_SHARE_JS_DIALOG_SCHEME
|
||||
methodName:FBSDK_APP_INVITE_METHOD_NAME
|
||||
methodVersion:nil
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) {
|
||||
[self _handleCompletionWithDialogResults:response.responseParameters error:response.error];
|
||||
};
|
||||
|
||||
[self _logDialogShow];
|
||||
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
BOOL useSafariViewController = [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameAppInvite];
|
||||
if ([self _canShowNative]) {
|
||||
FBSDKBridgeAPIRequest *nativeRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative
|
||||
scheme:FBSDK_CANOPENURL_FACEBOOK
|
||||
methodName:FBSDK_APP_INVITE_METHOD_NAME
|
||||
methodVersion:FBSDK_APP_INVITE_METHOD_MIN_VERSION
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
void (^nativeCompletionBlock)(FBSDKBridgeAPIResponse *) = ^(FBSDKBridgeAPIResponse *response) {
|
||||
if (response.error.code == FBSDKAppVersionUnsupportedErrorCode) {
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webBridgeRequest
|
||||
useSafariViewController:useSafariViewController
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:completionBlock];
|
||||
} else {
|
||||
completionBlock(response);
|
||||
}
|
||||
};
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:nativeRequest
|
||||
useSafariViewController:useSafariViewController
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:nativeCompletionBlock];
|
||||
} else {
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webBridgeRequest
|
||||
useSafariViewController:useSafariViewController
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:completionBlock];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
return [FBSDKShareUtility validateAppInviteContent:self.content error:errorRef];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (BOOL)_canShowNative
|
||||
{
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
BOOL useNativeDialog = [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameAppInvite];
|
||||
return (useNativeDialog && [FBSDKInternalUtility isFacebookAppInstalled]);
|
||||
}
|
||||
|
||||
- (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error
|
||||
{
|
||||
if (error) {
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
} else {
|
||||
[self _invokeDelegateDidCompleteWithResults:results];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
NSDictionary * parameters =@{
|
||||
FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed,
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_delegate appInviteDialog:self didCompleteWithResults:[results copy]];
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidFailWithError:(NSError *)error
|
||||
{
|
||||
NSDictionary * parameters =@{
|
||||
FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Failed,
|
||||
FBSDKAppEventParameterDialogErrorMessage : [NSString stringWithFormat:@"%@", error]
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_delegate appInviteDialog:self didFailWithError:error];
|
||||
}
|
||||
|
||||
- (void)_logDialogShow
|
||||
{
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow
|
||||
valueToSum:nil
|
||||
parameters:nil
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
}
|
||||
|
||||
@end
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM(NSUInteger, FBSDKGameRequestActionType)
|
||||
@abstract Additional context about the nature of the request.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKGameRequestActionType)
|
||||
{
|
||||
/*! No action type */
|
||||
FBSDKGameRequestActionTypeNone = 0,
|
||||
/*! Send action type: The user is sending an object to the friends. */
|
||||
FBSDKGameRequestActionTypeSend,
|
||||
/*! Ask For action type: The user is asking for an object from friends. */
|
||||
FBSDKGameRequestActionTypeAskFor,
|
||||
/*! Turn action type: It is the turn of the friends to play against the user in a match. (no object) */
|
||||
FBSDKGameRequestActionTypeTurn,
|
||||
};
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilters)
|
||||
@abstract Filter for who can be displayed in the multi-friend selector.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilter)
|
||||
{
|
||||
/*! No filter, all friends can be displayed. */
|
||||
FBSDKGameRequestFilterNone = 0,
|
||||
/*! Friends using the app can be displayed. */
|
||||
FBSDKGameRequestFilterAppUsers,
|
||||
/*! Friends not using the app can be displayed. */
|
||||
FBSDKGameRequestFilterAppNonUsers,
|
||||
};
|
||||
|
||||
/*!
|
||||
@abstract A model for a game request.
|
||||
*/
|
||||
@interface FBSDKGameRequestContent : NSObject <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract Used when defining additional context about the nature of the request.
|
||||
@discussion The parameter 'objectID' is required if the action type is either
|
||||
'FBSDKGameRequestSendActionType' or 'FBSDKGameRequestAskForActionType'.
|
||||
@seealso objectID
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKGameRequestActionType actionType;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another game request content.
|
||||
@param content The other content
|
||||
@return YES if the receiver's values are equal to the other content's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToGameRequestContent:(FBSDKGameRequestContent *)content;
|
||||
|
||||
/*!
|
||||
@abstract Additional freeform data you may pass for tracking. This will be stored as part of
|
||||
the request objects created. The maximum length is 255 characters.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *data;
|
||||
|
||||
/*!
|
||||
@abstract This controls the set of friends someone sees if a multi-friend selector is shown.
|
||||
It is FBSDKGameRequestNoFilter by default, meaning that all friends can be shown.
|
||||
If specify as FBSDKGameRequestAppUsersFilter, only friends who use the app will be shown.
|
||||
On the other hands, use FBSDKGameRequestAppNonUsersFilter to filter only friends who do not use the app.
|
||||
@discussion The parameter name is preserved to be consistent with the counter part on desktop.
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKGameRequestFilter filters;
|
||||
|
||||
/*!
|
||||
@abstract A plain-text message to be sent as part of the request. This text will surface in the App Center view
|
||||
of the request, but not on the notification jewel. Required parameter.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *message;
|
||||
|
||||
/*!
|
||||
@abstract The Open Graph object ID of the object being sent.
|
||||
@seealso actionType
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *objectID;
|
||||
|
||||
/*!
|
||||
@abstract An array of user IDs, usernames or invite tokens (NSString) of people to send request.
|
||||
@discussion These may or may not be a friend of the sender. If this is specified by the app,
|
||||
the sender will not have a choice of recipients. If not, the sender will see a multi-friend selector
|
||||
|
||||
This is equivalent to the "to" parameter when using the web game request dialog.
|
||||
*/
|
||||
@property (nonatomic, copy) NSArray *recipients;
|
||||
|
||||
/*!
|
||||
@abstract An array of user IDs that will be included in the dialog as the first suggested friends.
|
||||
Cannot be used together with filters.
|
||||
@discussion This is equivalent to the "suggestions" parameter when using the web game request dialog.
|
||||
*/
|
||||
@property (nonatomic, copy) NSArray *recipientSuggestions;
|
||||
|
||||
/*!
|
||||
@deprecated Use `recipientSuggestions` instead.
|
||||
*/
|
||||
@property (nonatomic, copy) NSArray *suggestions __attribute__ ((deprecated("use recipientSuggestions instead")));
|
||||
|
||||
/*!
|
||||
@abstract The title for the dialog.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
|
||||
/*!
|
||||
@deprecated Use `recipients` instead.
|
||||
*/
|
||||
@property (nonatomic, copy) NSArray *to __attribute__ ((deprecated("use recipients instead")));
|
||||
|
||||
@end
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKGameRequestContent.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#define FBSDK_APP_REQUEST_CONTENT_TO_KEY @"to"
|
||||
#define FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY @"message"
|
||||
#define FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY @"actionType"
|
||||
#define FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY @"objectID"
|
||||
#define FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY @"filters"
|
||||
#define FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY @"suggestions"
|
||||
#define FBSDK_APP_REQUEST_CONTENT_DATA_KEY @"data"
|
||||
#define FBSDK_APP_REQUEST_CONTENT_TITLE_KEY @"title"
|
||||
|
||||
@implementation FBSDKGameRequestContent
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
-(void)setRecipients:(NSArray *)recipients
|
||||
{
|
||||
[FBSDKShareUtility assertCollection:recipients ofClass:[NSString class] name:@"recipients"];
|
||||
if (![_recipients isEqual:recipients]) {
|
||||
_recipients = [recipients copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setRecipientSuggestions:(NSArray *)recipientSuggestions
|
||||
{
|
||||
[FBSDKShareUtility assertCollection:recipientSuggestions ofClass:[NSString class] name:@"recipientSuggestions"];
|
||||
if (![_recipientSuggestions isEqual:recipientSuggestions]) {
|
||||
_recipientSuggestions = [recipientSuggestions copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)suggestions
|
||||
{
|
||||
return self.recipientSuggestions;
|
||||
}
|
||||
|
||||
- (void)setSuggestions:(NSArray *)suggestions
|
||||
{
|
||||
self.recipientSuggestions = suggestions;
|
||||
}
|
||||
|
||||
- (NSArray *)to
|
||||
{
|
||||
return self.recipients;
|
||||
}
|
||||
|
||||
- (void)setTo:(NSArray *)to
|
||||
{
|
||||
self.recipients = to;
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[FBSDKMath hashWithInteger:_actionType],
|
||||
[_data hash],
|
||||
[FBSDKMath hashWithInteger:_filters],
|
||||
[_message hash],
|
||||
[_objectID hash],
|
||||
[_recipientSuggestions hash],
|
||||
[_title hash],
|
||||
[_recipients hash],
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKGameRequestContent class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToGameRequestContent:(FBSDKGameRequestContent *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToGameRequestContent:(FBSDKGameRequestContent *)content
|
||||
{
|
||||
return (content &&
|
||||
_actionType == content.actionType &&
|
||||
_filters == content.filters &&
|
||||
[FBSDKInternalUtility object:_data isEqualToObject:content.data] &&
|
||||
[FBSDKInternalUtility object:_message isEqualToObject:content.message] &&
|
||||
[FBSDKInternalUtility object:_objectID isEqualToObject:content.objectID] &&
|
||||
[FBSDKInternalUtility object:_recipientSuggestions isEqualToObject:content.recipientSuggestions] &&
|
||||
[FBSDKInternalUtility object:_title isEqualToObject:content.title] &&
|
||||
[FBSDKInternalUtility object:_recipients isEqualToObject:content.recipients]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_actionType = [decoder decodeIntegerForKey:FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY];
|
||||
_data = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_DATA_KEY];
|
||||
_filters = [decoder decodeIntegerForKey:FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY];
|
||||
_message = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY];
|
||||
_objectID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY];
|
||||
_recipientSuggestions = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY];
|
||||
_title = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_TITLE_KEY];
|
||||
_recipients = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_APP_REQUEST_CONTENT_TO_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeInteger:_actionType forKey:FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY];
|
||||
[encoder encodeObject:_data forKey:FBSDK_APP_REQUEST_CONTENT_DATA_KEY];
|
||||
[encoder encodeInteger:_filters forKey:FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY];
|
||||
[encoder encodeObject:_message forKey:FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY];
|
||||
[encoder encodeObject:_objectID forKey:FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY];
|
||||
[encoder encodeObject:_recipientSuggestions forKey:FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY];
|
||||
[encoder encodeObject:_title forKey:FBSDK_APP_REQUEST_CONTENT_TITLE_KEY];
|
||||
[encoder encodeObject:_recipients forKey:FBSDK_APP_REQUEST_CONTENT_TO_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKGameRequestContent *copy = [[FBSDKGameRequestContent alloc] init];
|
||||
copy->_actionType = _actionType;
|
||||
copy->_data = [_data copy];
|
||||
copy->_filters = _filters;
|
||||
copy->_message = [_message copy];
|
||||
copy->_objectID = [_objectID copy];
|
||||
copy->_recipientSuggestions = [_recipientSuggestions copy];
|
||||
copy->_title = [_title copy];
|
||||
copy->_recipients = [_recipients copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKGameRequestContent.h>
|
||||
|
||||
@protocol FBSDKGameRequestDialogDelegate;
|
||||
|
||||
/*!
|
||||
@abstract A dialog for sending game requests.
|
||||
*/
|
||||
@interface FBSDKGameRequestDialog : NSObject
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build up a game request with content and a delegate.
|
||||
@param content The content for the game request.
|
||||
@param delegate The receiver's delegate.
|
||||
*/
|
||||
+ (instancetype)showWithContent:(FBSDKGameRequestContent *)content delegate:(id<FBSDKGameRequestDialogDelegate>)delegate;
|
||||
|
||||
/*!
|
||||
@abstract The receiver's delegate or nil if it doesn't have a delegate.
|
||||
*/
|
||||
@property (nonatomic, weak) id<FBSDKGameRequestDialogDelegate> delegate;
|
||||
|
||||
/*!
|
||||
@abstract The content for game request.
|
||||
*/
|
||||
@property (nonatomic, copy) FBSDKGameRequestContent *content;
|
||||
|
||||
/*!
|
||||
@abstract Specifies whether frictionless requests are enabled.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL frictionlessRequestsEnabled;
|
||||
|
||||
/*!
|
||||
@abstract A Boolean value that indicates whether the receiver can initiate a game request.
|
||||
@discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is
|
||||
required but not available. This method does not validate the content on the receiver, so this can be checked before
|
||||
building up the content.
|
||||
@see validateWithError:
|
||||
@result YES if the receiver can share, otherwise NO.
|
||||
*/
|
||||
- (BOOL)canShow;
|
||||
|
||||
/*!
|
||||
@abstract Begins the game request from the receiver.
|
||||
@result YES if the receiver was able to show the dialog, otherwise NO.
|
||||
*/
|
||||
- (BOOL)show;
|
||||
|
||||
/*!
|
||||
@abstract Validates the content on the receiver.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@return YES if the content is valid, otherwise NO.
|
||||
*/
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract A delegate for FBSDKGameRequestDialog.
|
||||
@discussion The delegate is notified with the results of the game request as long as the application has permissions to
|
||||
receive the information. For example, if the person is not signed into the containing app, the shower may not be able
|
||||
to distinguish between completion of a game request and cancellation.
|
||||
*/
|
||||
@protocol FBSDKGameRequestDialogDelegate <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the game request completes without error.
|
||||
@param gameRequestDialog The FBSDKGameRequestDialog that completed.
|
||||
@param results The results from the dialog. This may be nil or empty.
|
||||
*/
|
||||
- (void)gameRequestDialog:(FBSDKGameRequestDialog *)gameRequestDialog didCompleteWithResults:(NSDictionary *)results;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the game request encounters an error.
|
||||
@param gameRequestDialog The FBSDKGameRequestDialog that completed.
|
||||
@param error The error.
|
||||
*/
|
||||
- (void)gameRequestDialog:(FBSDKGameRequestDialog *)gameRequestDialog didFailWithError:(NSError *)error;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the game request dialog is cancelled.
|
||||
@param gameRequestDialog The FBSDKGameRequestDialog that completed.
|
||||
*/
|
||||
- (void)gameRequestDialogDidCancel:(FBSDKGameRequestDialog *)gameRequestDialog;
|
||||
|
||||
@end
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKGameRequestDialog.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKGameRequestFrictionlessRecipientCache.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
@interface FBSDKGameRequestDialog () <FBSDKWebDialogDelegate>
|
||||
@end
|
||||
|
||||
@implementation FBSDKGameRequestDialog
|
||||
{
|
||||
BOOL _dialogIsFrictionless;
|
||||
FBSDKWebDialog *_webDialog;
|
||||
}
|
||||
|
||||
#define FBSDK_APP_REQUEST_METHOD_NAME @"apprequests"
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
static FBSDKGameRequestFrictionlessRecipientCache *_recipientCache = nil;
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [FBSDKGameRequestDialog class]) {
|
||||
_recipientCache = [[FBSDKGameRequestFrictionlessRecipientCache alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
+ (instancetype)showWithContent:(FBSDKGameRequestContent *)content delegate:(id<FBSDKGameRequestDialogDelegate>)delegate
|
||||
{
|
||||
FBSDKGameRequestDialog *dialog = [[self alloc] init];
|
||||
dialog.content = content;
|
||||
dialog.delegate = delegate;
|
||||
[dialog show];
|
||||
return dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_webDialog = [[FBSDKWebDialog alloc] init];
|
||||
_webDialog.delegate = self;
|
||||
_webDialog.name = FBSDK_APP_REQUEST_METHOD_NAME;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_webDialog.delegate = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canShow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)show
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canShow]) {
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"Game request dialog is not available."];
|
||||
[_delegate gameRequestDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self validateWithError:&error]) {
|
||||
[_delegate gameRequestDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
|
||||
FBSDKGameRequestContent *content = self.content;
|
||||
|
||||
if (error) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:[content.recipients componentsJoinedByString:@","] forKey:@"to"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.message forKey:@"message"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:[self _actionTypeNameForActionType:content.actionType] forKey:@"action_type"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.objectID forKey:@"object_id"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:[self _filtersNameForFilters:content.filters] forKey:@"filters"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:[content.recipientSuggestions componentsJoinedByString:@","] forKey:@"suggestions"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.data forKey:@"data"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.title forKey:@"title"];
|
||||
|
||||
// check if we are sending to a specific set of recipients. if we are and they are all frictionless recipients, we
|
||||
// can perform this action without displaying the web dialog
|
||||
_webDialog.deferVisibility = NO;
|
||||
NSArray *recipients = content.recipients;
|
||||
if (_frictionlessRequestsEnabled && recipients) {
|
||||
// specify these parameters to get the frictionless recipients from the dialog when it is presented
|
||||
parameters[@"frictionless"] = @YES;
|
||||
parameters[@"get_frictionless_recipients"] = @YES;
|
||||
|
||||
_dialogIsFrictionless = YES;
|
||||
if ([_recipientCache recipientsAreFrictionless:recipients]) {
|
||||
_webDialog.deferVisibility = YES;
|
||||
}
|
||||
}
|
||||
|
||||
_webDialog.parameters = parameters;
|
||||
[_webDialog show];
|
||||
[FBSDKInternalUtility registerTransientObject:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
return [FBSDKShareUtility validateGameRequestContent:self.content error:errorRef];
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKWebDialogDelegate
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
if (_dialogIsFrictionless && results) {
|
||||
[_recipientCache updateWithResults:results];
|
||||
}
|
||||
[self _cleanUp];
|
||||
|
||||
NSError *error = [FBSDKShareError errorWithCode:[FBSDKTypeUtility unsignedIntegerValue:results[@"error_code"]]
|
||||
message:[FBSDKTypeUtility stringValue:results[@"error_message"]]];
|
||||
if (!error.code) {
|
||||
// reformat "to[x]" keys into an array.
|
||||
int counter = 0;
|
||||
NSMutableArray *toArray = [NSMutableArray array];
|
||||
while (true) {
|
||||
NSString *key = [NSString stringWithFormat:@"to[%d]", counter++];
|
||||
if (results[key]) {
|
||||
[toArray addObject:results[key]];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (toArray.count) {
|
||||
NSMutableDictionary *mutableResults = [results mutableCopy];
|
||||
mutableResults[@"to"] = toArray;
|
||||
results = mutableResults;
|
||||
}
|
||||
}
|
||||
[self _handleCompletionWithDialogResults:results error:error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[self _cleanUp];
|
||||
[self _handleCompletionWithDialogResults:nil error:error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[self _cleanUp];
|
||||
[_delegate gameRequestDialogDidCancel:self];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_cleanUp
|
||||
{
|
||||
_dialogIsFrictionless = NO;
|
||||
}
|
||||
|
||||
- (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error
|
||||
{
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
switch (error.code) {
|
||||
case 0:{
|
||||
[_delegate gameRequestDialog:self didCompleteWithResults:results];
|
||||
break;
|
||||
}
|
||||
case 4201:{
|
||||
[_delegate gameRequestDialogDidCancel:self];
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
[_delegate gameRequestDialog:self didFailWithError:error];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)_actionTypeNameForActionType:(FBSDKGameRequestActionType)actionType
|
||||
{
|
||||
switch (actionType) {
|
||||
case FBSDKGameRequestActionTypeNone:{
|
||||
return nil;
|
||||
}
|
||||
case FBSDKGameRequestActionTypeSend:{
|
||||
return @"send";
|
||||
}
|
||||
case FBSDKGameRequestActionTypeAskFor:{
|
||||
return @"askfor";
|
||||
}
|
||||
case FBSDKGameRequestActionTypeTurn:{
|
||||
return @"turn";
|
||||
}
|
||||
default:{
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)_filtersNameForFilters:(FBSDKGameRequestFilter)filters
|
||||
{
|
||||
switch (filters) {
|
||||
case FBSDKGameRequestFilterNone:{
|
||||
return nil;
|
||||
}
|
||||
case FBSDKGameRequestFilterAppUsers:{
|
||||
return @"app_users";
|
||||
}
|
||||
case FBSDKGameRequestFilterAppNonUsers:{
|
||||
return @"app_non_users";
|
||||
}
|
||||
default:{
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKButton.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKLikeObjectType.h>
|
||||
#import <FBSDKShareKit/FBSDKLiking.h>
|
||||
|
||||
/*!
|
||||
@abstract A button to like an object.
|
||||
@discussion Tapping the receiver will invoke an API call to the Facebook app through a fast-app-switch that allows
|
||||
the object to be liked. Upon return to the calling app, the view will update with the new state. If the
|
||||
currentAccessToken has "publish_actions" permission and the object is an Open Graph object, then the like can happen
|
||||
seamlessly without the fast-app-switch.
|
||||
*/
|
||||
@interface FBSDKLikeButton : FBSDKButton <FBSDKLiking>
|
||||
|
||||
/*!
|
||||
@abstract If YES, a sound is played when the receiver is toggled.
|
||||
|
||||
@default YES
|
||||
*/
|
||||
@property (nonatomic, assign, getter = isSoundEnabled) BOOL soundEnabled;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,294 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeButton.h"
|
||||
#import "FBSDKLikeButton+Internal.h"
|
||||
|
||||
#import "FBSDKCheckmarkIcon.h"
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKLikeActionController.h"
|
||||
#import "FBSDKLikeControl+Internal.h"
|
||||
|
||||
#define FBSDK_LIKE_BUTTON_ANIMATION_DURATION 0.2
|
||||
#define FBSDK_LIKE_BUTTON_ANIMATION_SPRING_DAMPING 0.3
|
||||
#define FBSDK_LIKE_BUTTON_ANIMATION_SPRING_VELOCITY 0.2
|
||||
|
||||
@implementation FBSDKLikeButton
|
||||
{
|
||||
BOOL _isExplicitlyDisabled;
|
||||
FBSDKLikeActionController *_likeActionController;
|
||||
NSString *_objectID;
|
||||
FBSDKLikeObjectType _objectType;
|
||||
}
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if ([FBSDKLikeButton class] == self) {
|
||||
// ensure that we have updated the dialog configs if we haven't already
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[_likeActionController endContentAccess];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (FBSDKLikeActionController *)likeActionController
|
||||
{
|
||||
[self _ensureLikeActionController:NO];
|
||||
return _likeActionController;
|
||||
}
|
||||
|
||||
- (void)setLikeActionController:(FBSDKLikeActionController *)likeActionController
|
||||
{
|
||||
[self _setLikeActionController:likeActionController];
|
||||
}
|
||||
|
||||
- (NSString *)objectID
|
||||
{
|
||||
return _objectID;
|
||||
}
|
||||
|
||||
- (void)setObjectID:(NSString *)objectID
|
||||
{
|
||||
if (![_objectID isEqualToString:objectID]) {
|
||||
_objectID = objectID;
|
||||
[self checkImplicitlyDisabled];
|
||||
[self _resetLikeActionController];
|
||||
}
|
||||
}
|
||||
|
||||
- (FBSDKLikeObjectType)objectType
|
||||
{
|
||||
return _objectType;
|
||||
}
|
||||
|
||||
- (void)setObjectType:(FBSDKLikeObjectType)objectType
|
||||
{
|
||||
if (_objectType != objectType) {
|
||||
_objectType = objectType;
|
||||
[self _resetLikeActionController];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[self _ensureLikeActionController:YES];
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKButtonImpressionTracking
|
||||
|
||||
- (NSDictionary *)analyticsParameters
|
||||
{
|
||||
UIView *superview = self.superview;
|
||||
while (superview && ![superview isKindOfClass:[FBSDKLikeControl class]]) {
|
||||
superview = superview.superview;
|
||||
}
|
||||
if ([superview isKindOfClass:[FBSDKLikeControl class]]) {
|
||||
return ((FBSDKLikeControl *)superview).analyticsParameters;
|
||||
}
|
||||
return @{
|
||||
@"object_id": (self.objectID ?: [NSNull null]),
|
||||
@"object_type": (NSStringFromFBSDKLikeObjectType(self.objectType) ?: [NSNull null]),
|
||||
@"sound_enabled": @(self.soundEnabled),
|
||||
};
|
||||
}
|
||||
|
||||
- (NSString *)impressionTrackingEventName
|
||||
{
|
||||
return FBSDKAppEventNameFBSDKLikeButtonImpression;
|
||||
}
|
||||
|
||||
- (NSString *)impressionTrackingIdentifier
|
||||
{
|
||||
return self.objectID;
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKButton
|
||||
|
||||
- (void)configureButton
|
||||
{
|
||||
self.soundEnabled = YES;
|
||||
|
||||
NSString *title =
|
||||
NSLocalizedStringWithDefaultValue(@"LikeButton.Like", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings],
|
||||
@"Like",
|
||||
@"The label for the FBSDKLikeButton when the object is not currently liked.");
|
||||
NSString *selectedTitle =
|
||||
NSLocalizedStringWithDefaultValue(@"LikeButton.Liked", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings],
|
||||
@"Liked",
|
||||
@"The label for the FBSDKLikeButton when the object is currently liked.");
|
||||
|
||||
UIColor *backgroundColor = [self defaultBackgroundColor];
|
||||
UIColor *highlightedColor = [self defaultHighlightedColor];
|
||||
UIColor *selectedColor = [self defaultSelectedColor];
|
||||
UIColor *selectedHighlightedColor = [UIColor colorWithRed:99.0/255.0 green:119.0/255.0 blue:178.0/255.0 alpha:1.0];
|
||||
|
||||
[self configureWithIcon:nil
|
||||
title:title
|
||||
backgroundColor:backgroundColor
|
||||
highlightedColor:highlightedColor
|
||||
selectedTitle:selectedTitle
|
||||
selectedIcon:[[FBSDKCheckmarkIcon alloc] init]
|
||||
selectedColor:selectedColor
|
||||
selectedHighlightedColor:selectedHighlightedColor];
|
||||
|
||||
[self addTarget:self action:@selector(_handleTap:) forControlEvents:UIControlEventTouchUpInside];
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserver:self
|
||||
selector:@selector(_likeActionControllerDidDisableNotification:)
|
||||
name:FBSDKLikeActionControllerDidDisableNotification
|
||||
object:nil];
|
||||
[nc addObserver:self
|
||||
selector:@selector(_likeActionControllerDidResetNotification:)
|
||||
name:FBSDKLikeActionControllerDidResetNotification
|
||||
object:nil];
|
||||
[nc addObserver:self
|
||||
selector:@selector(_likeActionControllerDidUpdateNotification:)
|
||||
name:FBSDKLikeActionControllerDidUpdateNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (BOOL)isImplicitlyDisabled
|
||||
{
|
||||
return !self.objectID || [FBSDKLikeActionController isDisabled];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_ensureLikeActionController:(BOOL)notifyKVO
|
||||
{
|
||||
if (!_likeActionController) {
|
||||
FBSDKLikeActionController *likeActionController = [FBSDKLikeActionController likeActionControllerForObjectID:_objectID
|
||||
objectType:_objectType];
|
||||
if (notifyKVO) {
|
||||
self.likeActionController = likeActionController;
|
||||
} else {
|
||||
[self _setLikeActionController:likeActionController];
|
||||
}
|
||||
[likeActionController endContentAccess];
|
||||
self.selected = _likeActionController.objectIsLiked;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_handleTap:(FBSDKLikeButton *)likeButton
|
||||
{
|
||||
[self logTapEventWithEventName:FBSDKAppEventNameFBSDKLikeButtonDidTap parameters:[self analyticsParameters]];
|
||||
[self _ensureLikeActionController:YES];
|
||||
[_likeActionController toggleLikeWithSoundEnabled:self.soundEnabled
|
||||
analyticsParameters:[self analyticsParameters]
|
||||
fromViewController:[FBSDKInternalUtility viewControllerforView:self]];
|
||||
}
|
||||
|
||||
- (void)_like:(id)sender
|
||||
{
|
||||
[_likeActionController toggleLikeWithSoundEnabled:_soundEnabled
|
||||
analyticsParameters:[self analyticsParameters]
|
||||
fromViewController:[FBSDKInternalUtility viewControllerforView:self]];
|
||||
}
|
||||
|
||||
- (void)_likeActionControllerDidDisableNotification:(NSNotification *)notification
|
||||
{
|
||||
[self checkImplicitlyDisabled];
|
||||
}
|
||||
|
||||
- (void)_likeActionControllerDidResetNotification:(NSNotification *)notification
|
||||
{
|
||||
[self _resetLikeActionController];
|
||||
[self _ensureLikeActionController:YES];
|
||||
}
|
||||
|
||||
- (void)_likeActionControllerDidUpdateNotification:(NSNotification *)notification
|
||||
{
|
||||
[self _ensureLikeActionController:YES];
|
||||
FBSDKLikeActionController *likeActionController = (FBSDKLikeActionController *)notification.object;
|
||||
NSString *objectID = likeActionController.objectID;
|
||||
if ([self.objectID isEqualToString:objectID]) {
|
||||
BOOL animated = [notification.userInfo[FBSDKLikeActionControllerAnimatedKey] boolValue];
|
||||
[self _setSelected:likeActionController.objectIsLiked animated:animated];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_resetLikeActionController
|
||||
{
|
||||
self.likeActionController = nil;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)_setLikeActionController:(FBSDKLikeActionController *)likeActionController
|
||||
{
|
||||
if (_likeActionController != likeActionController) {
|
||||
[_likeActionController endContentAccess];
|
||||
_likeActionController = likeActionController;
|
||||
[_likeActionController beginContentAccess];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_setSelected:(BOOL)selected animated:(BOOL)animated
|
||||
{
|
||||
if (self.selected != selected) {
|
||||
if (animated) {
|
||||
CFTimeInterval duration = FBSDK_LIKE_BUTTON_ANIMATION_DURATION;
|
||||
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState;
|
||||
UIImageView *imageView = self.imageView;
|
||||
imageView.frame = [self imageRectForContentRect:UIEdgeInsetsInsetRect(self.bounds, self.contentEdgeInsets)];
|
||||
[UIView animateWithDuration:duration delay:0.0 options:options animations:^{
|
||||
CGPoint iconImageViewCenter = imageView.center;
|
||||
imageView.frame = CGRectMake(iconImageViewCenter.x, iconImageViewCenter.y, 0.0, 0.0);
|
||||
} completion:^(BOOL animateOutFinished) {
|
||||
self.selected = selected;
|
||||
CGPoint iconImageViewCenter = imageView.center;
|
||||
imageView.frame = CGRectMake(iconImageViewCenter.x, iconImageViewCenter.y, 0.0, 0.0);
|
||||
|
||||
void(^animations)(void) = ^{
|
||||
imageView.frame = [self imageRectForContentRect:UIEdgeInsetsInsetRect(self.bounds, self.contentEdgeInsets)];
|
||||
};
|
||||
if ([UIView respondsToSelector:@selector(animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)]) {
|
||||
[UIView animateWithDuration:(duration * 2)
|
||||
delay:0.0
|
||||
usingSpringWithDamping:FBSDK_LIKE_BUTTON_ANIMATION_SPRING_DAMPING
|
||||
initialSpringVelocity:FBSDK_LIKE_BUTTON_ANIMATION_SPRING_VELOCITY
|
||||
options:options
|
||||
animations:animations
|
||||
completion:NULL];
|
||||
} else {
|
||||
[UIView animateWithDuration:(duration * 2)
|
||||
delay:0.0
|
||||
options:options
|
||||
animations:animations
|
||||
completion:NULL];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
self.selected = selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,139 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKLikeObjectType.h>
|
||||
#import <FBSDKShareKit/FBSDKLiking.h>
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM (NSUInteger, FBSDKLikeControlAuxiliaryPosition)
|
||||
|
||||
@abstract Specifies the position of the auxiliary view relative to the like button.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKLikeControlAuxiliaryPosition)
|
||||
{
|
||||
/*! The auxiliary view is inline with the like button. */
|
||||
FBSDKLikeControlAuxiliaryPositionInline,
|
||||
/*! The auxiliary view is above the like button. */
|
||||
FBSDKLikeControlAuxiliaryPositionTop,
|
||||
/*! The auxiliary view is below the like button. */
|
||||
FBSDKLikeControlAuxiliaryPositionBottom,
|
||||
};
|
||||
|
||||
/*!
|
||||
@abstract Converts an FBSDKLikeControlAuxiliaryPosition to an NSString.
|
||||
*/
|
||||
FBSDK_EXTERN NSString *NSStringFromFBSDKLikeControlAuxiliaryPosition(FBSDKLikeControlAuxiliaryPosition auxiliaryPosition);
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM(NSUInteger, FBSDKLikeControlHorizontalAlignment)
|
||||
|
||||
@abstract Specifies the horizontal alignment for FBSDKLikeControlStyleStandard with
|
||||
FBSDKLikeControlAuxiliaryPositionTop or FBSDKLikeControlAuxiliaryPositionBottom.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKLikeControlHorizontalAlignment)
|
||||
{
|
||||
/*! The subviews are left aligned. */
|
||||
FBSDKLikeControlHorizontalAlignmentLeft,
|
||||
/*! The subviews are center aligned. */
|
||||
FBSDKLikeControlHorizontalAlignmentCenter,
|
||||
/*! The subviews are right aligned. */
|
||||
FBSDKLikeControlHorizontalAlignmentRight,
|
||||
};
|
||||
|
||||
/*!
|
||||
@abstract Converts an FBSDKLikeControlHorizontalAlignment to an NSString.
|
||||
*/
|
||||
FBSDK_EXTERN NSString *NSStringFromFBSDKLikeControlHorizontalAlignment(FBSDKLikeControlHorizontalAlignment horizontalAlignment);
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM (NSUInteger, FBSDKLikeControlStyle)
|
||||
|
||||
@abstract Specifies the style of a like control.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKLikeControlStyle)
|
||||
{
|
||||
/*! Displays the button and the social sentence. */
|
||||
FBSDKLikeControlStyleStandard = 0,
|
||||
/*! Displays the button and a box that contains the like count. */
|
||||
FBSDKLikeControlStyleBoxCount,
|
||||
};
|
||||
|
||||
/*!
|
||||
@abstract Converts an FBSDKLikeControlStyle to an NSString.
|
||||
*/
|
||||
FBSDK_EXTERN NSString *NSStringFromFBSDKLikeControlStyle(FBSDKLikeControlStyle style);
|
||||
|
||||
/*!
|
||||
@class FBSDKLikeControl
|
||||
|
||||
@abstract UI control to like an object in the Facebook graph.
|
||||
|
||||
@discussion Taps on the like button within this control will invoke an API call to the Facebook app through a
|
||||
fast-app-switch that allows the user to like the object. Upon return to the calling app, the view will update
|
||||
with the new state and send actions for the UIControlEventValueChanged event.
|
||||
*/
|
||||
@interface FBSDKLikeControl : UIControl <FBSDKLiking>
|
||||
|
||||
/*!
|
||||
@abstract The foreground color to use for the content of the receiver.
|
||||
*/
|
||||
@property (nonatomic, strong) UIColor *foregroundColor;
|
||||
|
||||
/*!
|
||||
@abstract The position for the auxiliary view for the receiver.
|
||||
|
||||
@see FBSDKLikeControlAuxiliaryPosition
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKLikeControlAuxiliaryPosition likeControlAuxiliaryPosition;
|
||||
|
||||
/*!
|
||||
@abstract The text alignment of the social sentence.
|
||||
|
||||
@discussion This value is only valid for FBSDKLikeControlStyleStandard with
|
||||
FBSDKLikeControlAuxiliaryPositionTop|Bottom.
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKLikeControlHorizontalAlignment likeControlHorizontalAlignment;
|
||||
|
||||
/*!
|
||||
@abstract The style to use for the receiver.
|
||||
|
||||
@see FBSDKLikeControlStyle
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKLikeControlStyle likeControlStyle;
|
||||
|
||||
/*!
|
||||
@abstract The preferred maximum width (in points) for autolayout.
|
||||
|
||||
@discussion This property affects the size of the receiver when layout constraints are applied to it. During layout,
|
||||
if the text extends beyond the width specified by this property, the additional text is flowed to one or more new
|
||||
lines, thereby increasing the height of the receiver.
|
||||
*/
|
||||
@property (nonatomic, assign) CGFloat preferredMaxLayoutWidth;
|
||||
|
||||
/*!
|
||||
@abstract If YES, a sound is played when the receiver is toggled.
|
||||
|
||||
@default YES
|
||||
*/
|
||||
@property (nonatomic, assign, getter = isSoundEnabled) BOOL soundEnabled;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,664 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeControl.h"
|
||||
#import "FBSDKLikeControl+Internal.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKLikeActionController.h"
|
||||
#import "FBSDKLikeBoxView.h"
|
||||
#import "FBSDKLikeButton+Internal.h"
|
||||
#import "FBSDKLikeButton.h"
|
||||
|
||||
#define kFBLikeControlAnimationDuration 0.2
|
||||
#define kFBLikeControlSocialSentenceAnimationOffset 10.0
|
||||
|
||||
static void *FBSDKLikeControlKVOLikeActionControllerContext = &FBSDKLikeControlKVOLikeActionControllerContext;
|
||||
|
||||
NSString *NSStringFromFBSDKLikeControlAuxiliaryPosition(FBSDKLikeControlAuxiliaryPosition auxiliaryPosition)
|
||||
{
|
||||
switch (auxiliaryPosition) {
|
||||
case FBSDKLikeControlAuxiliaryPositionBottom:
|
||||
return @"bottom";
|
||||
case FBSDKLikeControlAuxiliaryPositionInline:
|
||||
return @"inline";
|
||||
case FBSDKLikeControlAuxiliaryPositionTop:
|
||||
return @"top";
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString *NSStringFromFBSDKLikeControlHorizontalAlignment(FBSDKLikeControlHorizontalAlignment horizontalAlignment)
|
||||
{
|
||||
switch (horizontalAlignment) {
|
||||
case FBSDKLikeControlHorizontalAlignmentCenter:
|
||||
return @"center";
|
||||
case FBSDKLikeControlHorizontalAlignmentLeft:
|
||||
return @"left";
|
||||
case FBSDKLikeControlHorizontalAlignmentRight:
|
||||
return @"right";
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSString *NSStringFromFBSDKLikeControlStyle(FBSDKLikeControlStyle style)
|
||||
{
|
||||
switch (style) {
|
||||
case FBSDKLikeControlStyleBoxCount:
|
||||
return @"box_count";
|
||||
case FBSDKLikeControlStyleStandard:
|
||||
return @"standard";
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
typedef struct FBSDKLikeControlLayout
|
||||
{
|
||||
CGSize contentSize;
|
||||
CGRect likeButtonFrame;
|
||||
CGRect auxiliaryViewFrame;
|
||||
} FBSDKLikeControlLayout;
|
||||
|
||||
typedef CGSize (^fbsdk_like_control_sizing_block_t)(UIView *subview, CGSize constrainedSize);
|
||||
|
||||
@implementation FBSDKLikeControl
|
||||
{
|
||||
BOOL _isExplicitlyDisabled;
|
||||
FBSDKLikeBoxView *_likeBoxView;
|
||||
FBSDKLikeButton *_likeButton;
|
||||
UIView *_likeButtonContainer;
|
||||
UILabel *_socialSentenceLabel;
|
||||
}
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if ([FBSDKLikeControl class] == self) {
|
||||
// ensure that we have updated the dialog configs if we haven't already
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
[self _initializeContent];
|
||||
if (CGRectEqualToRect(frame, CGRectZero)) {
|
||||
[self sizeToFit];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [super initWithCoder:decoder])) {
|
||||
[self _initializeContent];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[_likeButton removeObserver:self forKeyPath:@"likeActionController"];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
||||
{
|
||||
[super setBackgroundColor:backgroundColor];
|
||||
_likeButtonContainer.backgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
- (void)setForegroundColor:(UIColor *)foregroundColor
|
||||
{
|
||||
if (![_foregroundColor isEqual:foregroundColor]) {
|
||||
_foregroundColor = foregroundColor;
|
||||
[_likeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
_socialSentenceLabel.textColor = foregroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled
|
||||
{
|
||||
_isExplicitlyDisabled = !enabled;
|
||||
[self _updateEnabled];
|
||||
}
|
||||
|
||||
- (void)setLikeControlAuxiliaryPosition:(FBSDKLikeControlAuxiliaryPosition)likeControlAuxiliaryPosition
|
||||
{
|
||||
if (_likeControlAuxiliaryPosition != likeControlAuxiliaryPosition) {
|
||||
_likeControlAuxiliaryPosition = likeControlAuxiliaryPosition;
|
||||
[self _updateLikeBoxCaretPosition];
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsUpdateConstraints];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setLikeControlHorizontalAlignment:(FBSDKLikeControlHorizontalAlignment)likeControlHorizontalAlignment
|
||||
{
|
||||
if (_likeControlHorizontalAlignment != likeControlHorizontalAlignment) {
|
||||
_likeControlHorizontalAlignment = likeControlHorizontalAlignment;
|
||||
[self _updateLikeBoxCaretPosition];
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsUpdateConstraints];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setLikeControlStyle:(FBSDKLikeControlStyle)likeControlStyle
|
||||
{
|
||||
if (_likeControlStyle != likeControlStyle) {
|
||||
_likeControlStyle = likeControlStyle;
|
||||
[self _updateLikeBoxCaretPosition];
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsUpdateConstraints];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)objectID
|
||||
{
|
||||
return _likeButton.objectID;
|
||||
}
|
||||
|
||||
- (void)setObjectID:(NSString *)objectID
|
||||
{
|
||||
if (![_likeButton.objectID isEqualToString:objectID]) {
|
||||
_likeButton.objectID = objectID;
|
||||
[self _updateEnabled];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
}
|
||||
|
||||
- (FBSDKLikeObjectType)objectType
|
||||
{
|
||||
return _likeButton.objectType;
|
||||
}
|
||||
|
||||
- (void)setObjectType:(FBSDKLikeObjectType)objectType
|
||||
{
|
||||
if (_likeButton.objectType != objectType) {
|
||||
_likeButton.objectType = objectType;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setOpaque:(BOOL)opaque
|
||||
{
|
||||
[super setOpaque:opaque];
|
||||
_likeButtonContainer.opaque = opaque;
|
||||
}
|
||||
|
||||
- (BOOL)isSoundEnabled
|
||||
{
|
||||
return _likeButton.soundEnabled;
|
||||
}
|
||||
|
||||
- (void)setSoundEnabled:(BOOL)soundEnabled
|
||||
{
|
||||
_likeButton.soundEnabled = soundEnabled;
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
CGFloat width = self.preferredMaxLayoutWidth;
|
||||
if (width == 0) {
|
||||
width = CGFLOAT_MAX;
|
||||
}
|
||||
CGRect bounds = CGRectMake(0.0, 0.0, width, CGFLOAT_MAX);
|
||||
return [self _layoutWithBounds:bounds subviewSizingBlock:^CGSize(UIView *subview, CGSize constrainedSize) {
|
||||
if ([subview respondsToSelector:@selector(setPreferredMaxLayoutWidth:)]) {
|
||||
[(id)subview setPreferredMaxLayoutWidth:constrainedSize.width];
|
||||
}
|
||||
return subview.intrinsicContentSize;
|
||||
}].contentSize;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
NSString *objectID = self.objectID;
|
||||
if (objectID) {
|
||||
FBSDKViewImpressionTracker *impressionTracker =
|
||||
[FBSDKViewImpressionTracker impressionTrackerWithEventName:FBSDKAppEventNameFBSDKLikeControlImpression];
|
||||
[impressionTracker logImpressionWithIdentifier:objectID parameters:[self analyticsParameters]];
|
||||
}
|
||||
|
||||
[self _ensureLikeActionController];
|
||||
|
||||
CGRect bounds = self.bounds;
|
||||
CGSize(^sizingBlock)(UIView *, CGSize) = ^CGSize(UIView *subview, CGSize constrainedSize) {
|
||||
return [subview sizeThatFits:constrainedSize];
|
||||
};
|
||||
FBSDKLikeControlLayout layout = [self _layoutWithBounds:bounds subviewSizingBlock:sizingBlock];
|
||||
|
||||
UIView *auxiliaryView = [self _auxiliaryView];
|
||||
_likeBoxView.hidden = (_likeBoxView != auxiliaryView);
|
||||
_socialSentenceLabel.hidden = (_socialSentenceLabel != auxiliaryView);
|
||||
|
||||
_likeButtonContainer.frame = layout.likeButtonFrame;
|
||||
_likeButton.frame = _likeButtonContainer.bounds;
|
||||
auxiliaryView.frame = layout.auxiliaryViewFrame;
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
switch (self.likeControlAuxiliaryPosition) {
|
||||
case FBSDKLikeControlAuxiliaryPositionInline:{
|
||||
size.height = MAX(size.height, CGRectGetHeight(self.bounds));
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlAuxiliaryPositionTop:
|
||||
case FBSDKLikeControlAuxiliaryPositionBottom:{
|
||||
size.width = MAX(size.width, CGRectGetWidth(self.bounds));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CGRect bounds = CGRectMake(0.0, 0.0, size.width, size.height);
|
||||
return [self _layoutWithBounds:bounds subviewSizingBlock:^CGSize(UIView *subview, CGSize constrainedSize) {
|
||||
return [subview sizeThatFits:constrainedSize];
|
||||
}].contentSize;
|
||||
}
|
||||
|
||||
#pragma mark - Internal Methods
|
||||
|
||||
- (NSDictionary *)analyticsParameters
|
||||
{
|
||||
return @{
|
||||
@"auxiliary_position": NSStringFromFBSDKLikeControlAuxiliaryPosition(self.likeControlAuxiliaryPosition),
|
||||
@"horizontal_alignment": NSStringFromFBSDKLikeControlHorizontalAlignment(self.likeControlHorizontalAlignment),
|
||||
@"object_id": (self.objectID ?: [NSNull null]),
|
||||
@"object_type": (NSStringFromFBSDKLikeObjectType(self.objectType) ?: [NSNull null]),
|
||||
@"sound_enabled": @(self.soundEnabled),
|
||||
@"style": NSStringFromFBSDKLikeControlStyle(self.likeControlStyle),
|
||||
};
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (UIView *)_auxiliaryView
|
||||
{
|
||||
[self _ensureLikeActionController];
|
||||
switch (_likeControlStyle) {
|
||||
case FBSDKLikeControlStyleStandard:{
|
||||
return (_socialSentenceLabel.text.length == 0 ? nil : _socialSentenceLabel);
|
||||
}
|
||||
case FBSDKLikeControlStyleBoxCount:{
|
||||
return (_likeButton.likeActionController.likeCountString == nil ? nil : _likeBoxView);
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (CGFloat)_auxiliaryViewPadding
|
||||
{
|
||||
switch (_likeControlStyle) {
|
||||
case FBSDKLikeControlStyleStandard:{
|
||||
return 8.0;
|
||||
}
|
||||
case FBSDKLikeControlStyleBoxCount:{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
- (void)_ensureLikeActionController
|
||||
{
|
||||
FBSDKLikeActionController *likeActionController = _likeButton.likeActionController;
|
||||
if (likeActionController) {
|
||||
_socialSentenceLabel.text = likeActionController.socialSentence;
|
||||
_likeBoxView.text = likeActionController.likeCountString;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_handleLikeButtonTap:(FBSDKLikeButton *)likeButton
|
||||
{
|
||||
[self _ensureLikeActionController];
|
||||
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
|
||||
- (void)_initializeContent
|
||||
{
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
_foregroundColor = [UIColor blackColor];
|
||||
|
||||
_likeButtonContainer = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
_likeButtonContainer.backgroundColor = self.backgroundColor;
|
||||
_likeButtonContainer.opaque = self.opaque;
|
||||
[self addSubview:_likeButtonContainer];
|
||||
|
||||
_likeButton = [[FBSDKLikeButton alloc] initWithFrame:CGRectZero];
|
||||
[_likeButton addTarget:self action:@selector(_handleLikeButtonTap:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[_likeButtonContainer addSubview:_likeButton];
|
||||
|
||||
_socialSentenceLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_socialSentenceLabel.font = [UIFont systemFontOfSize:11.0];
|
||||
_socialSentenceLabel.numberOfLines = 2;
|
||||
[self addSubview:_socialSentenceLabel];
|
||||
|
||||
_likeBoxView = [[FBSDKLikeBoxView alloc] initWithFrame:CGRectZero];
|
||||
[self addSubview:_likeBoxView];
|
||||
|
||||
// use KVO to monitor changes to the likeActionController instance on FBSDKButton in order to avoid race conditions
|
||||
// between notification observers
|
||||
[_likeButton addObserver:self
|
||||
forKeyPath:@"likeActionController"
|
||||
options:NSKeyValueObservingOptionInitial
|
||||
context:FBSDKLikeControlKVOLikeActionControllerContext];
|
||||
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserver:self
|
||||
selector:@selector(_likeActionControllerDidDisableNotification:)
|
||||
name:FBSDKLikeActionControllerDidDisableNotification
|
||||
object:nil];
|
||||
[nc addObserver:self
|
||||
selector:@selector(_likeActionControllerDidUpdateNotification:)
|
||||
name:FBSDKLikeActionControllerDidUpdateNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if (context == FBSDKLikeControlKVOLikeActionControllerContext) {
|
||||
[self _likeActionControllerDidUpdateWithAnimated:NO];
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
static void FBSDKLikeControlApplyHorizontalAlignment(CGRect *frameRef,
|
||||
CGRect bounds,
|
||||
FBSDKLikeControlHorizontalAlignment alignment)
|
||||
{
|
||||
if (frameRef == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGRect frame = *frameRef;
|
||||
switch (alignment) {
|
||||
case FBSDKLikeControlHorizontalAlignmentLeft:{
|
||||
frame.origin.x = CGRectGetMinX(bounds);
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlHorizontalAlignmentCenter:{
|
||||
frame.origin.x = CGRectGetMinX(bounds) + floorf((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2);
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlHorizontalAlignmentRight:{
|
||||
frame.origin.x = CGRectGetMinX(bounds) + CGRectGetWidth(bounds) - CGRectGetWidth(frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*frameRef = frame;
|
||||
}
|
||||
|
||||
static CGFloat FBSDKLikeControlPaddedDistance(CGFloat distance, CGFloat padding, BOOL includeDistance)
|
||||
{
|
||||
return (distance == 0.0 ? 0.0 : (includeDistance ? distance : 0.0) + padding);
|
||||
}
|
||||
|
||||
static CGSize FBSDKLikeControlCalculateContentSize(FBSDKLikeControlLayout layout)
|
||||
{
|
||||
return CGSizeMake(MAX(CGRectGetMaxX(layout.likeButtonFrame), CGRectGetMaxX(layout.auxiliaryViewFrame)),
|
||||
MAX(CGRectGetMaxY(layout.likeButtonFrame), CGRectGetMaxY(layout.auxiliaryViewFrame)));
|
||||
|
||||
}
|
||||
|
||||
- (FBSDKLikeControlLayout)_layoutWithBounds:(CGRect)bounds
|
||||
subviewSizingBlock:(fbsdk_like_control_sizing_block_t)subviewSizingBlock
|
||||
{
|
||||
FBSDKLikeControlLayout layout;
|
||||
|
||||
CGSize likeButtonSize = subviewSizingBlock(_likeButton, bounds.size);
|
||||
layout.likeButtonFrame = CGRectMake(CGRectGetMinX(bounds),
|
||||
CGRectGetMinY(bounds),
|
||||
likeButtonSize.width,
|
||||
likeButtonSize.height);
|
||||
layout.auxiliaryViewFrame = CGRectZero;
|
||||
|
||||
UIView *auxiliaryView = [self _auxiliaryView];
|
||||
CGFloat auxiliaryViewPadding = [self _auxiliaryViewPadding];
|
||||
CGSize auxiliaryViewSize = CGSizeZero;
|
||||
switch (self.likeControlAuxiliaryPosition) {
|
||||
case FBSDKLikeControlAuxiliaryPositionInline:{
|
||||
if (auxiliaryView) {
|
||||
auxiliaryViewSize = CGSizeMake((CGRectGetWidth(bounds) -
|
||||
auxiliaryViewPadding -
|
||||
CGRectGetWidth(layout.likeButtonFrame)),
|
||||
CGRectGetHeight(bounds));
|
||||
auxiliaryViewSize = subviewSizingBlock(auxiliaryView, auxiliaryViewSize);
|
||||
|
||||
layout.auxiliaryViewFrame = CGRectMake(CGRectGetMinX(bounds),
|
||||
CGRectGetMinY(bounds),
|
||||
auxiliaryViewSize.width,
|
||||
MAX(auxiliaryViewSize.height,
|
||||
CGRectGetHeight(layout.likeButtonFrame)));
|
||||
}
|
||||
|
||||
// align the views next to each other for sizing
|
||||
FBSDKLikeControlApplyHorizontalAlignment(&layout.likeButtonFrame,
|
||||
bounds,
|
||||
FBSDKLikeControlHorizontalAlignmentLeft);
|
||||
if (auxiliaryView) {
|
||||
layout.auxiliaryViewFrame.origin.x = CGRectGetMaxX(layout.likeButtonFrame) + auxiliaryViewPadding;
|
||||
}
|
||||
|
||||
// calculate the size before offsetting the horizontal alignment, using the total calculated width
|
||||
layout.contentSize = FBSDKLikeControlCalculateContentSize(layout);
|
||||
|
||||
// layout the subviews next to each other
|
||||
switch (self.likeControlHorizontalAlignment) {
|
||||
case FBSDKLikeControlHorizontalAlignmentLeft:{
|
||||
// already done
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlHorizontalAlignmentCenter:{
|
||||
layout.likeButtonFrame.origin.x = floorf((CGRectGetWidth(bounds) - layout.contentSize.width) / 2);
|
||||
if (auxiliaryView) {
|
||||
layout.auxiliaryViewFrame.origin.x = (CGRectGetMaxX(layout.likeButtonFrame) +
|
||||
auxiliaryViewPadding);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlHorizontalAlignmentRight:{
|
||||
layout.likeButtonFrame.origin.x = CGRectGetMaxX(bounds) - CGRectGetWidth(layout.likeButtonFrame);
|
||||
if (auxiliaryView) {
|
||||
layout.auxiliaryViewFrame.origin.x = (CGRectGetMinX(layout.likeButtonFrame) -
|
||||
auxiliaryViewPadding -
|
||||
CGRectGetWidth(layout.auxiliaryViewFrame));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlAuxiliaryPositionTop:{
|
||||
if (auxiliaryView) {
|
||||
auxiliaryViewSize = CGSizeMake(CGRectGetWidth(bounds),
|
||||
(CGRectGetHeight(bounds) -
|
||||
auxiliaryViewPadding -
|
||||
CGRectGetHeight(layout.likeButtonFrame)));
|
||||
auxiliaryViewSize = subviewSizingBlock(auxiliaryView, auxiliaryViewSize);
|
||||
|
||||
layout.auxiliaryViewFrame = CGRectMake(CGRectGetMinX(bounds),
|
||||
CGRectGetMinY(bounds),
|
||||
MAX(auxiliaryViewSize.width,
|
||||
CGRectGetWidth(layout.likeButtonFrame)),
|
||||
auxiliaryViewSize.height);
|
||||
}
|
||||
layout.likeButtonFrame.origin.y = FBSDKLikeControlPaddedDistance(CGRectGetMaxY(layout.auxiliaryViewFrame),
|
||||
auxiliaryViewPadding,
|
||||
YES);
|
||||
|
||||
// calculate the size before offsetting the horizontal alignment, using the total calculated width
|
||||
layout.contentSize = FBSDKLikeControlCalculateContentSize(layout);
|
||||
|
||||
FBSDKLikeControlApplyHorizontalAlignment(&layout.likeButtonFrame, bounds, self.likeControlHorizontalAlignment);
|
||||
FBSDKLikeControlApplyHorizontalAlignment(&layout.auxiliaryViewFrame,
|
||||
bounds,
|
||||
self.likeControlHorizontalAlignment);
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlAuxiliaryPositionBottom:{
|
||||
if (auxiliaryView) {
|
||||
auxiliaryViewSize = CGSizeMake(CGRectGetWidth(bounds),
|
||||
(CGRectGetHeight(bounds) -
|
||||
auxiliaryViewPadding -
|
||||
CGRectGetHeight(layout.likeButtonFrame)));
|
||||
auxiliaryViewSize = subviewSizingBlock(auxiliaryView, auxiliaryViewSize);
|
||||
|
||||
layout.auxiliaryViewFrame = CGRectMake(CGRectGetMinX(bounds),
|
||||
CGRectGetMaxY(layout.likeButtonFrame) + auxiliaryViewPadding,
|
||||
MAX(auxiliaryViewSize.width,
|
||||
CGRectGetWidth(layout.likeButtonFrame)),
|
||||
auxiliaryViewSize.height);
|
||||
}
|
||||
|
||||
// calculate the size before offsetting the horizontal alignment, using the total calculated width
|
||||
layout.contentSize = FBSDKLikeControlCalculateContentSize(layout);
|
||||
|
||||
FBSDKLikeControlApplyHorizontalAlignment(&layout.likeButtonFrame, bounds, self.likeControlHorizontalAlignment);
|
||||
FBSDKLikeControlApplyHorizontalAlignment(&layout.auxiliaryViewFrame,
|
||||
bounds,
|
||||
self.likeControlHorizontalAlignment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
- (void)_likeActionControllerDidDisableNotification:(NSNotification *)notification
|
||||
{
|
||||
[self _updateEnabled];
|
||||
}
|
||||
|
||||
- (void)_likeActionControllerDidUpdateNotification:(NSNotification *)notification
|
||||
{
|
||||
[self _ensureLikeActionController];
|
||||
FBSDKLikeActionController *likeActionController = (FBSDKLikeActionController *)notification.object;
|
||||
NSString *objectID = likeActionController.objectID;
|
||||
if ([self.objectID isEqualToString:objectID]) {
|
||||
BOOL animated = [notification.userInfo[FBSDKLikeActionControllerAnimatedKey] boolValue];
|
||||
[self _likeActionControllerDidUpdateWithAnimated:animated];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_likeActionControllerDidUpdateWithAnimated:(BOOL)animated
|
||||
{
|
||||
FBSDKLikeActionController *likeActionController = _likeButton.likeActionController;
|
||||
NSString *objectID = likeActionController.objectID;
|
||||
if ([self.objectID isEqualToString:objectID]) {
|
||||
_likeBoxView.text = _likeButton.likeActionController.likeCountString;
|
||||
|
||||
if (animated) {
|
||||
void(^hideView)(UIView *) = ^(UIView *view){
|
||||
view.alpha = 0.0;
|
||||
CGRect frame = view.frame;
|
||||
frame.origin.y += kFBLikeControlSocialSentenceAnimationOffset;
|
||||
view.frame = frame;
|
||||
};
|
||||
[UIView animateWithDuration:kFBLikeControlAnimationDuration animations:^{
|
||||
hideView(_socialSentenceLabel);
|
||||
} completion:^(BOOL finished) {
|
||||
_socialSentenceLabel.text = likeActionController.socialSentence;
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsUpdateConstraints];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
[self layoutIfNeeded];
|
||||
hideView(_socialSentenceLabel);
|
||||
|
||||
[UIView animateWithDuration:kFBLikeControlAnimationDuration animations:^{
|
||||
_socialSentenceLabel.alpha = 1.0;
|
||||
[self setNeedsLayout];
|
||||
[self layoutIfNeeded];
|
||||
}];
|
||||
}];
|
||||
} else {
|
||||
_socialSentenceLabel.text = likeActionController.socialSentence;
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsUpdateConstraints];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
|
||||
[self sendActionsForControlEvents:UIControlEventValueChanged];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_updateEnabled
|
||||
{
|
||||
BOOL enabled = (!_isExplicitlyDisabled &&
|
||||
self.objectID &&
|
||||
![FBSDKLikeActionController isDisabled]);
|
||||
BOOL currentEnabled = [self isEnabled];
|
||||
[super setEnabled:enabled];
|
||||
if (currentEnabled != enabled) {
|
||||
[self invalidateIntrinsicContentSize];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_updateLikeBoxCaretPosition
|
||||
{
|
||||
if (self.likeControlStyle != FBSDKLikeControlStyleBoxCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (self.likeControlAuxiliaryPosition) {
|
||||
case FBSDKLikeControlAuxiliaryPositionInline:{
|
||||
switch (self.likeControlHorizontalAlignment) {
|
||||
case FBSDKLikeControlHorizontalAlignmentLeft:
|
||||
case FBSDKLikeControlHorizontalAlignmentCenter:{
|
||||
_likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionLeft;
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlHorizontalAlignmentRight:{
|
||||
_likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionRight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlAuxiliaryPositionTop:{
|
||||
_likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionBottom;
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeControlAuxiliaryPositionBottom:{
|
||||
_likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionTop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM (NSUInteger, FBSDKLikeObjectType)
|
||||
@abstract Specifies the type of object referenced by the objectID for likes.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKLikeObjectType)
|
||||
{
|
||||
/*! The objectID refers to an unknown object type. */
|
||||
FBSDKLikeObjectTypeUnknown = 0,
|
||||
/*! The objectID refers to an Open Graph object. */
|
||||
FBSDKLikeObjectTypeOpenGraph,
|
||||
/*! The objectID refers to an Page object. */
|
||||
FBSDKLikeObjectTypePage,
|
||||
};
|
||||
|
||||
/*!
|
||||
@abstract Converts an FBLikeControlObjectType to an NSString.
|
||||
*/
|
||||
FBSDK_EXTERN NSString *NSStringFromFBSDKLikeObjectType(FBSDKLikeObjectType objectType);
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeObjectType.h"
|
||||
|
||||
NSString *NSStringFromFBSDKLikeObjectType(FBSDKLikeObjectType objectType)
|
||||
{
|
||||
switch (objectType) {
|
||||
case FBSDKLikeObjectTypeUnknown:
|
||||
return @"unknown";
|
||||
case FBSDKLikeObjectTypeOpenGraph:
|
||||
return @"open_graph";
|
||||
case FBSDKLikeObjectTypePage:
|
||||
return @"page";
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/*!
|
||||
@abstract The common interface for components that initiate liking.
|
||||
@see FBSDKLikeButton
|
||||
@see FBSDKLikeControl
|
||||
*/
|
||||
@protocol FBSDKLiking <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract The objectID for the object to like.
|
||||
|
||||
@discussion This value may be an Open Graph object ID or a string representation of an URL that describes an
|
||||
Open Graph object. The objects may be public objects, like pages, or objects that are defined by your application.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *objectID;
|
||||
|
||||
/*!
|
||||
@abstract The type of object referenced by the objectID.
|
||||
|
||||
@discussion If the objectType is unknown, the control will determine the objectType by querying the server with the
|
||||
objectID. Specifying a value for the objectType is an optimization that should be used if the type is known by the
|
||||
consumer. Consider setting the objectType if it is known when setting the objectID.
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKLikeObjectType objectType;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharing.h>
|
||||
|
||||
/*!
|
||||
@abstract A dialog for sharing content through Messenger.
|
||||
*/
|
||||
@interface FBSDKMessageDialog : NSObject <FBSDKSharingDialog>
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to show a Message Share Dialog with content and a delegate.
|
||||
@param content The content to be shared.
|
||||
@param delegate The receiver's delegate.
|
||||
*/
|
||||
+ (instancetype)showWithContent:(id<FBSDKSharingContent>)content delegate:(id<FBSDKSharingDelegate>)delegate;
|
||||
|
||||
@end
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKMessageDialog.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareDefines.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareOpenGraphContent.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
#import "FBSDKShareVideoContent.h"
|
||||
|
||||
#define FBSDK_MESSAGE_DIALOG_APP_SCHEME @"fb-messenger-api"
|
||||
#define FBSDK_MESSAGE_METHOD_MIN_VERSION @"20140430"
|
||||
|
||||
@implementation FBSDKMessageDialog
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if ([FBSDKMessageDialog class] == self) {
|
||||
[FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_MESSENGER];
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
+ (instancetype)showWithContent:(id<FBSDKSharingContent>)content delegate:(id<FBSDKSharingDelegate>)delegate
|
||||
{
|
||||
FBSDKMessageDialog *dialog = [[self alloc] init];
|
||||
dialog.shareContent = content;
|
||||
dialog.delegate = delegate;
|
||||
[dialog show];
|
||||
return dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
@synthesize shareContent = _shareContent;
|
||||
@synthesize shouldFailOnDataError = _shouldFailOnDataError;
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canShow
|
||||
{
|
||||
return [self _canShowNative];
|
||||
}
|
||||
|
||||
- (BOOL)show
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canShow]) {
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"Message dialog is not available."];
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self validateWithError:&error]) {
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
NSDictionary *parameters = [FBSDKShareUtility parametersForShareContent:shareContent
|
||||
shouldFailOnDataError:self.shouldFailOnDataError];
|
||||
NSString *methodName = ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]] ?
|
||||
FBSDK_SHARE_OPEN_GRAPH_METHOD_NAME :
|
||||
FBSDK_SHARE_METHOD_NAME);
|
||||
FBSDKBridgeAPIRequest *request;
|
||||
request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative
|
||||
scheme:FBSDK_MESSAGE_DIALOG_APP_SCHEME
|
||||
methodName:methodName
|
||||
methodVersion:FBSDK_MESSAGE_METHOD_MIN_VERSION
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
BOOL useSafariViewController = [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameMessage];
|
||||
FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) {
|
||||
[self _handleCompletionWithDialogResults:response.responseParameters response:response];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
};
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request
|
||||
useSafariViewController:useSafariViewController
|
||||
fromViewController:nil
|
||||
completionBlock:completionBlock];
|
||||
|
||||
[self _logDialogShow];
|
||||
[FBSDKInternalUtility registerTransientObject:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if (!shareContent) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
if (![FBSDKShareUtility validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)shareContent name:@"videoURL" error:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return [FBSDKShareUtility validateShareContent:self.shareContent error:errorRef];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (BOOL)_canShowNative
|
||||
{
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
BOOL useNativeDialog = [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameMessage];
|
||||
return (useNativeDialog && [FBSDKInternalUtility isMessengerAppInstalled]);
|
||||
}
|
||||
|
||||
- (void)_handleCompletionWithDialogResults:(NSDictionary *)results response:(FBSDKBridgeAPIResponse *)response
|
||||
{
|
||||
NSString *completionGesture = results[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL] ||
|
||||
response.isCancelled) {
|
||||
[self _invokeDelegateDidCancel];
|
||||
} else if (response.error) {
|
||||
[self _invokeDelegateDidFailWithError:response.error];
|
||||
} else {
|
||||
[self _invokeDelegateDidCompleteWithResults:results];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidCancel
|
||||
{
|
||||
NSDictionary * parameters =@{
|
||||
FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Cancelled,
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_delegate sharerDidCancel:self];
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
NSDictionary * parameters =@{
|
||||
FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed,
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_delegate sharer:self didCompleteWithResults:[results copy]];
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidFailWithError:(NSError *)error
|
||||
{
|
||||
NSMutableDictionary * parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:FBSDKAppEventsDialogOutcomeValue_Failed, FBSDKAppEventParameterDialogOutcome, nil];
|
||||
if (error) {
|
||||
parameters[FBSDKAppEventParameterDialogErrorMessage] = [NSString stringWithFormat:@"%@", error];
|
||||
}
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
}
|
||||
|
||||
- (void)_logDialogShow
|
||||
{
|
||||
NSString *contentType;
|
||||
if([self.shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeOpenGraph;
|
||||
} else if ([self.shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeStatus;
|
||||
} else if ([self.shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypePhoto;
|
||||
} else if ([self.shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeVideo;
|
||||
} else {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeUnknown;
|
||||
}
|
||||
|
||||
NSDictionary *parameters = @{FBSDKAppEventParameterDialogShareContentType : contentType};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogShow
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKButton.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharingButton.h>
|
||||
|
||||
/*!
|
||||
@abstract A button to send content through Messenger.
|
||||
@discussion Tapping the receiver will invoke the FBSDKShareDialog with the attached shareContent. If the dialog cannot
|
||||
be shown, the button will be disable.
|
||||
*/
|
||||
@interface FBSDKSendButton : FBSDKButton <FBSDKSharingButton>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKSendButton.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKMessageDialog.h"
|
||||
#import "FBSDKMessengerIcon.h"
|
||||
|
||||
@interface FBSDKSendButton () <FBSDKButtonImpressionTracking>
|
||||
@end
|
||||
|
||||
@implementation FBSDKSendButton
|
||||
{
|
||||
FBSDKMessageDialog *_dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (id<FBSDKSharingContent>)shareContent
|
||||
{
|
||||
return _dialog.shareContent;
|
||||
}
|
||||
|
||||
- (void)setShareContent:(id<FBSDKSharingContent>)shareContent
|
||||
{
|
||||
_dialog.shareContent = shareContent;
|
||||
[self checkImplicitlyDisabled];
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKButtonImpressionTracking
|
||||
|
||||
- (NSDictionary *)analyticsParameters
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *)impressionTrackingEventName
|
||||
{
|
||||
return FBSDKAppEventNameFBSDKSendButtonImpression;
|
||||
}
|
||||
|
||||
- (NSString *)impressionTrackingIdentifier
|
||||
{
|
||||
return @"send";
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKButton
|
||||
|
||||
- (void)configureButton
|
||||
{
|
||||
NSString *title =
|
||||
NSLocalizedStringWithDefaultValue(@"SendButton.Send", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings],
|
||||
@"Send",
|
||||
@"The label for FBSDKSendButton");
|
||||
|
||||
UIColor *backgroundColor = [UIColor colorWithRed:0.0 green:132.0/255.0 blue:1.0 alpha:1.0];
|
||||
UIColor *highlightedColor = [UIColor colorWithRed:0.0 green:111.0/255.0 blue:1.0 alpha:1.0];
|
||||
|
||||
[self configureWithIcon:[[FBSDKMessengerIcon alloc] init]
|
||||
title:title
|
||||
backgroundColor:backgroundColor
|
||||
highlightedColor:highlightedColor];
|
||||
|
||||
[self addTarget:self action:@selector(_share:) forControlEvents:UIControlEventTouchUpInside];
|
||||
_dialog = [[FBSDKMessageDialog alloc] init];
|
||||
}
|
||||
|
||||
- (BOOL)isImplicitlyDisabled
|
||||
{
|
||||
return ![_dialog canShow] || ![_dialog validateWithError:NULL];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_share:(id)sender
|
||||
{
|
||||
[self logTapEventWithEventName:FBSDKAppEventNameFBSDKSendButtonDidTap parameters:[self analyticsParameters]];
|
||||
[_dialog show];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphObject.h>
|
||||
#import <FBSDKShareKit/FBSDKSharing.h>
|
||||
|
||||
/*!
|
||||
@abstract A utility class for sharing through the graph API. Using this class requires an access token in
|
||||
[FBSDKAccessToken currentAccessToken] that has been granted the "publish_actions" permission.
|
||||
@discussion FBSDKShareAPI network requests are scheduled on the current run loop in the default run loop mode
|
||||
(like NSURLConnection). If you want to use FBSDKShareAPI in a background thread, you must manage the run loop
|
||||
yourself.
|
||||
*/
|
||||
@interface FBSDKShareAPI : NSObject <FBSDKSharing>
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build up a share API with content and a delegate.
|
||||
@param content The content to be shared.
|
||||
@param delegate The receiver's delegate.
|
||||
*/
|
||||
+ (instancetype)shareWithContent:(id<FBSDKSharingContent>)content delegate:(id<FBSDKSharingDelegate>)delegate;
|
||||
|
||||
/*!
|
||||
@abstract The message the person has provided through the custom dialog that will accompany the share content.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *message;
|
||||
|
||||
/*!
|
||||
@abstract The graph node to which content should be shared.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *graphNode;
|
||||
|
||||
/*!
|
||||
@abstract A Boolean value that indicates whether the receiver can send the share.
|
||||
@discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is
|
||||
required but not available. This method does not validate the content on the receiver, so this can be checked before
|
||||
building up the content.
|
||||
@see [FBSDKSharing validateWithError:]
|
||||
@result YES if the receiver can send, otherwise NO.
|
||||
*/
|
||||
- (BOOL)canShare;
|
||||
|
||||
/*!
|
||||
@abstract Creates an User Owned Open Graph object without an action.
|
||||
@param openGraphObject The open graph object to create.
|
||||
@discussion Use this method to create an object alone, when an action is not going to be posted with the object. If
|
||||
the object will be used within an action, just put the object in the action and share that as the shareContent and the
|
||||
object will be created in the process. The delegate will be messaged with the results.
|
||||
|
||||
Also see https://developers.facebook.com/docs/sharing/opengraph/object-api#objectapi-creatinguser
|
||||
|
||||
@result YES if the receiver was able to send the request to create the object, otherwise NO.
|
||||
*/
|
||||
- (BOOL)createOpenGraphObject:(FBSDKShareOpenGraphObject *)openGraphObject;
|
||||
|
||||
/*!
|
||||
@abstract Begins the send from the receiver.
|
||||
@result YES if the receiver was able to send the share, otherwise NO.
|
||||
*/
|
||||
- (BOOL)share;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,805 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareAPI.h"
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#import <AssetsLibrary/AssetsLibrary.h>
|
||||
#endif
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKAccessToken.h>
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequest.h>
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequestDataAttachment.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareDefines.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareLinkContent.h"
|
||||
#import "FBSDKShareOpenGraphAction.h"
|
||||
#import "FBSDKShareOpenGraphContent.h"
|
||||
#import "FBSDKShareOpenGraphObject.h"
|
||||
#import "FBSDKSharePhoto.h"
|
||||
#import "FBSDKSharePhotoContent.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
#import "FBSDKShareVideo.h"
|
||||
#import "FBSDKShareVideoContent.h"
|
||||
#import "FBSDKVideoUploader.h"
|
||||
|
||||
static NSString *const FBSDKShareAPIDefaultGraphNode = @"me";
|
||||
static NSString *const FBSDKShareAPIPhotosEdge = @"photos";
|
||||
static NSString *const FBSDKShareAPIVideosEdge = @"videos";
|
||||
static NSMutableArray *g_pendingFBSDKShareAPI;
|
||||
|
||||
@interface FBSDKShareAPI () <FBSDKVideoUploaderDelegate>
|
||||
@end
|
||||
|
||||
@implementation FBSDKShareAPI {
|
||||
NSFileHandle *_fileHandle;
|
||||
#if !TARGET_OS_TV
|
||||
ALAssetRepresentation *_assetRepresentation;
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (instancetype)shareWithContent:(id<FBSDKSharingContent>)content delegate:(id<FBSDKSharingDelegate>)delegate
|
||||
{
|
||||
FBSDKShareAPI *API = [[self alloc] init];
|
||||
API.shareContent = content;
|
||||
API.delegate = delegate;
|
||||
[API share];
|
||||
return API;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
@synthesize shareContent = _shareContent;
|
||||
@synthesize shouldFailOnDataError = _shouldFailOnDataError;
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
+ (ALAssetsLibrary *)defaultAssetsLibrary {
|
||||
static dispatch_once_t pred = 0;
|
||||
static ALAssetsLibrary *library = nil;
|
||||
dispatch_once(&pred, ^{
|
||||
library = [[fbsdkdfl_ALAssetsLibraryClass() alloc] init];
|
||||
});
|
||||
return library;
|
||||
}
|
||||
#endif
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if (self == [FBSDKShareAPI class]) {
|
||||
g_pendingFBSDKShareAPI = [[NSMutableArray alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_graphNode = FBSDKShareAPIDefaultGraphNode;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canShare
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)createOpenGraphObject:(FBSDKShareOpenGraphObject *)openGraphObject
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canShare]) {
|
||||
NSString *message = @"Share API is not available; verify 'canShare' returns YES";
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:message];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self _hasPublishActions]) {
|
||||
NSString *message = @"Warning: [FBSDKAccessToken currentAccessToken] is missing publish_actions permissions";
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:message];
|
||||
}
|
||||
if (!openGraphObject) {
|
||||
error = [FBSDKShareError requiredArgumentErrorWithName:@"openGraphObject" message:nil];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
|
||||
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
|
||||
void(^completionHandler)(id) = ^(NSDictionary *result) {
|
||||
[_delegate sharer:self didCompleteWithResults:result];
|
||||
};
|
||||
if (![self _stageOpenGraphObject:openGraphObject
|
||||
connection:connection
|
||||
stagingHandler:NULL
|
||||
completionHandler:completionHandler]) {
|
||||
return NO;
|
||||
}
|
||||
[connection start];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)share
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canShare]) {
|
||||
NSString *message = @"Share API is not available; verify 'canShare' returns YES";
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:message];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self _hasPublishActions]) {
|
||||
NSString *message = @"Warning: [FBSDKAccessToken currentAccessToken] is missing publish_actions permissions";
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:message];
|
||||
}
|
||||
if (![self validateWithError:&error]) {
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
|
||||
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
return [self _shareLinkContent:(FBSDKShareLinkContent *)shareContent];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
return [self _sharePhotoContent:(FBSDKSharePhotoContent *)shareContent];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
return [self _shareVideoContent:(FBSDKShareVideoContent *)shareContent];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
return [self _shareOpenGraphContent:(FBSDKShareOpenGraphContent *)shareContent];
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if (!shareContent) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:@"Share content cannot be null."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
if (shareContent.peopleIDs.count > 0) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"peopleIDs" value:shareContent.peopleIDs message:@"Cannot specify peopleIDs with FBSDKShareVideoContent."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (shareContent.placeID) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"placeID" value:shareContent.placeID message:@"Cannot specify place ID with FBSDKShareVideoContent."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
if (errorRef != NULL){
|
||||
*errorRef = nil;
|
||||
}
|
||||
return [FBSDKShareUtility validateShareContent:shareContent error:errorRef];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (NSString *)_graphPathWithSuffix:(NSString *)suffix, ... NS_REQUIRES_NIL_TERMINATION
|
||||
{
|
||||
NSMutableString *graphPath = [[NSMutableString alloc] initWithString:self.graphNode];
|
||||
va_list args;
|
||||
va_start(args, suffix);
|
||||
for (NSString *arg = suffix; arg != nil; arg = va_arg(args, NSString *)) {
|
||||
[graphPath appendFormat:@"/%@", arg];
|
||||
}
|
||||
va_end(args);
|
||||
return graphPath;
|
||||
}
|
||||
|
||||
- (void)_addCommonParameters:(NSMutableDictionary *)parameters content:(id<FBSDKSharingContent>)content
|
||||
{
|
||||
if (content.peopleIDs.count > 0) {
|
||||
NSString *tags;
|
||||
if ([content isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
NSMutableArray *tagsArray = [[NSMutableArray alloc] init];
|
||||
for (NSString *peopleID in content.peopleIDs) {
|
||||
[tagsArray addObject:@{ @"tag_uid" : peopleID }];
|
||||
}
|
||||
NSData *tagsJSON = [NSJSONSerialization dataWithJSONObject:tagsArray options:0 error:nil];
|
||||
tags = [[NSString alloc] initWithData:tagsJSON encoding:NSUTF8StringEncoding];
|
||||
} else {
|
||||
tags = [content.peopleIDs componentsJoinedByString:@","];
|
||||
}
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:tags forKey:@"tags"];
|
||||
}
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.placeID forKey:@"place"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:content.ref forKey:@"ref"];
|
||||
}
|
||||
|
||||
- (BOOL)_hasPublishActions
|
||||
{
|
||||
FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken];
|
||||
return [accessToken.permissions containsObject:@"publish_actions"];
|
||||
}
|
||||
|
||||
- (BOOL)_shareLinkContent:(FBSDKShareLinkContent *)linkContent
|
||||
{
|
||||
FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
} else {
|
||||
result = [FBSDKTypeUtility dictionaryValue:result];
|
||||
NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST
|
||||
forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:result[@"id"]]
|
||||
forKey:FBSDK_SHARE_RESULT_POST_ID_KEY];
|
||||
[_delegate sharer:self didCompleteWithResults:shareResults];
|
||||
}
|
||||
};
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[self _addCommonParameters:parameters content:linkContent];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"message"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL forKey:@"link"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.imageURL forKey:@"picture"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentTitle forKey:@"name"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentDescription forKey:@"description"];
|
||||
|
||||
[[[FBSDKGraphRequest alloc] initWithGraphPath:[self _graphPathWithSuffix:@"feed", nil]
|
||||
parameters:parameters
|
||||
HTTPMethod:@"POST"] startWithCompletionHandler:completionHandler];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_shareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent
|
||||
{
|
||||
// In order to create a new Open Graph action using a custom object that does not already exist (objectID or URL), you
|
||||
// must first send a request to post the object and then another to post the action. If a local image is supplied
|
||||
// with the object or action, that must be staged first and then referenced by the staging URL that is returned by
|
||||
// that request.
|
||||
FBSDKShareOpenGraphAction *action = openGraphContent.action;
|
||||
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
|
||||
void(^stagingHandler)(NSDictionary *) = ^(NSDictionary *stagedContainer) {
|
||||
NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:stagedContainer];
|
||||
[self _addCommonParameters:parameters content:openGraphContent];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"message"];
|
||||
|
||||
FBSDKGraphRequestHandler requestHandler = ^(FBSDKGraphRequestConnection *requestConnection,
|
||||
id result,
|
||||
NSError *requestError) {
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
if (requestError) {
|
||||
NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode
|
||||
message:@"Error sharing Open Graph content"
|
||||
underlyingError:requestError];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
} else if (result) {
|
||||
NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST
|
||||
forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:result[@"id"]]
|
||||
forKey:FBSDK_SHARE_RESULT_POST_ID_KEY];
|
||||
[_delegate sharer:self didCompleteWithResults:shareResults];
|
||||
}
|
||||
};
|
||||
NSString *graphPath = [self _graphPathWithSuffix:[FBSDKUtility URLEncode:action.actionType], nil];
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath
|
||||
parameters:parameters
|
||||
HTTPMethod:@"POST"];
|
||||
[self _connection:connection addRequest:request completionHandler:requestHandler];
|
||||
[connection start];
|
||||
};
|
||||
if (![self _stageOpenGraphValueContainer:action connection:connection stagingHandler:stagingHandler]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_sharePhotoContent:(FBSDKSharePhotoContent *)photoContent
|
||||
{
|
||||
NSArray *photos = photoContent.photos;
|
||||
NSMutableArray *requests = [[NSMutableArray alloc] init];
|
||||
for (FBSDKSharePhoto *photo in photos) {
|
||||
UIImage *image = photo.image;
|
||||
if (!image && [photo.imageURL isFileURL]) {
|
||||
image = [UIImage imageWithContentsOfFile:[photo.imageURL path]];
|
||||
}
|
||||
if (image) {
|
||||
NSString *graphPath = [self _graphPathWithSuffix:FBSDKShareAPIPhotosEdge, nil];
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[self _addCommonParameters:parameters content:photoContent];
|
||||
NSString *caption = photo.caption ?: self.message;
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:caption forKey:@"caption"];
|
||||
parameters[@"picture"] = image;
|
||||
[requests addObject:[[FBSDKGraphRequest alloc] initWithGraphPath:graphPath
|
||||
parameters:parameters
|
||||
HTTPMethod:@"POST"]];
|
||||
}
|
||||
}
|
||||
NSUInteger requestCount = [requests count];
|
||||
NSMutableArray *results = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *errors = [[NSMutableArray alloc] init];
|
||||
__block NSUInteger completedCount = 0;
|
||||
FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
result = [FBSDKTypeUtility dictionaryValue:result];
|
||||
[FBSDKInternalUtility array:results addObject:result];
|
||||
[FBSDKInternalUtility array:errors addObject:error];
|
||||
if (++completedCount != requestCount) {
|
||||
return;
|
||||
}
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
if ([errors count]) {
|
||||
[_delegate sharer:self didFailWithError:errors[0]];
|
||||
} else if ([results count]) {
|
||||
// each photo upload will be merged into the same post, so grab the post_id from the first and use that
|
||||
NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST
|
||||
forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
NSDictionary *firstResult = [FBSDKTypeUtility dictionaryValue:results[0]];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:firstResult[@"post_id"]]
|
||||
forKey:FBSDK_SHARE_RESULT_POST_ID_KEY];
|
||||
[_delegate sharer:self didCompleteWithResults:shareResults];
|
||||
}
|
||||
};
|
||||
for (FBSDKGraphRequest *request in requests) {
|
||||
[request startWithCompletionHandler:completionHandler];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_shareVideoContent:(FBSDKShareVideoContent *)videoContent
|
||||
{
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[self _addCommonParameters:parameters content:videoContent];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"description"];
|
||||
if ([[FBSDKAccessToken currentAccessToken].permissions containsObject:@"ads_management"]) {
|
||||
FBSDKSharePhoto *photo = videoContent.previewPhoto;
|
||||
UIImage *image = photo.image;
|
||||
if (!image && [photo.imageURL isFileURL]) {
|
||||
image = [UIImage imageWithContentsOfFile:[photo.imageURL path]];
|
||||
}
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:image forKey:@"thumb"];
|
||||
}
|
||||
FBSDKShareVideo *video = videoContent.video;
|
||||
NSURL *videoURL = video.videoURL;
|
||||
if ([videoURL isFileURL]) {
|
||||
NSError *fileError;
|
||||
_fileHandle = [NSFileHandle fileHandleForReadingFromURL:videoURL error:&fileError];
|
||||
if (!_fileHandle) {
|
||||
[_delegate sharer:self didFailWithError:fileError];
|
||||
return NO;
|
||||
}
|
||||
if (![self _addToPendingShareAPI]) {
|
||||
return NO;
|
||||
}
|
||||
FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[videoURL lastPathComponent]
|
||||
videoSize:(unsigned long)[_fileHandle seekToEndOfFile]
|
||||
parameters:parameters
|
||||
delegate:self];
|
||||
[videoUploader start];
|
||||
return YES;
|
||||
} else if (videoURL) {
|
||||
#if TARGET_OS_TV
|
||||
return NO;
|
||||
#else
|
||||
if (![self _addToPendingShareAPI]) {
|
||||
return NO;
|
||||
}
|
||||
[[FBSDKShareAPI defaultAssetsLibrary] assetForURL:videoURL resultBlock:^(ALAsset *asset) {
|
||||
_assetRepresentation = [asset defaultRepresentation];
|
||||
NSUInteger size = (NSUInteger)_assetRepresentation.size;
|
||||
FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[videoURL lastPathComponent]
|
||||
videoSize:size
|
||||
parameters:parameters
|
||||
delegate:self];
|
||||
[videoUploader start];
|
||||
} failureBlock:^(NSError *error) {
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
}];
|
||||
return YES;
|
||||
#endif
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_addEncodedParametersToDictionary:(NSMutableDictionary *)parameters
|
||||
key:(NSString *)key
|
||||
value:(id)value
|
||||
error:(NSError **)errorRef
|
||||
{
|
||||
if ([value isKindOfClass:[NSString class]] ||
|
||||
[value isKindOfClass:[NSNumber class]] ||
|
||||
[value isKindOfClass:[NSNull class]]) {
|
||||
parameters[key] = value;
|
||||
} else if ([value isKindOfClass:[NSArray class]]) {
|
||||
__block BOOL didEncode = YES;
|
||||
[(NSArray *)value enumerateObjectsUsingBlock:^(id subvalue, NSUInteger idx, BOOL *stop) {
|
||||
NSString *subkey = [[NSString alloc] initWithFormat:@"%@[%lu]", key, (unsigned long)idx];
|
||||
if (![self _addEncodedParametersToDictionary:parameters key:subkey value:subvalue error:errorRef]) {
|
||||
*stop = YES;
|
||||
didEncode = NO;
|
||||
}
|
||||
}];
|
||||
if (!didEncode) {
|
||||
return NO;
|
||||
}
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
__block BOOL didEncode = YES;
|
||||
[(NSDictionary *)value enumerateKeysAndObjectsUsingBlock:^(id subkey, id subvalue, BOOL *stop) {
|
||||
subkey = [[NSString alloc] initWithFormat:@"%@[%@]", key, subkey];
|
||||
if (![self _addEncodedParametersToDictionary:parameters key:subkey value:subvalue error:errorRef]) {
|
||||
*stop = YES;
|
||||
didEncode = NO;
|
||||
}
|
||||
}];
|
||||
if (!didEncode) {
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:key value:value message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_stageArray:(NSArray *)array
|
||||
connection:(FBSDKGraphRequestConnection *)connection
|
||||
stagingHandler:(void(^)(NSArray *stagedArray))stagingHandler
|
||||
{
|
||||
__block BOOL result = YES;
|
||||
__block NSUInteger pendingCount = 1;
|
||||
NSMutableArray *stagedArray = [[NSMutableArray alloc] initWithArray:array];
|
||||
void(^itemDidFail)(void) = ^{
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
result = NO;
|
||||
};
|
||||
void(^itemDidSucceed)(void) = ^{
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
if ((--pendingCount == 0) && (stagingHandler != NULL)) {
|
||||
stagingHandler(stagedArray);
|
||||
}
|
||||
};
|
||||
[array enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
|
||||
pendingCount++;
|
||||
void(^itemHandler)(id) = ^(id stagedValue) {
|
||||
if (stagedValue) {
|
||||
stagedArray[idx] = stagedValue;
|
||||
itemDidSucceed();
|
||||
} else {
|
||||
NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"value"
|
||||
value:item
|
||||
message:@"Error staging object."];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
itemDidFail();
|
||||
*stop = YES;
|
||||
result = NO;
|
||||
}
|
||||
};
|
||||
if (![self _stageValue:item connection:connection stagingHandler:itemHandler]) {
|
||||
itemDidFail();
|
||||
*stop = YES;
|
||||
result = NO;
|
||||
}
|
||||
}];
|
||||
if (result) {
|
||||
itemDidSucceed();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (BOOL)_stageOpenGraphObject:(FBSDKShareOpenGraphObject *)openGraphObject
|
||||
connection:(FBSDKGraphRequestConnection *)connection
|
||||
stagingHandler:(void(^)(id stagedObject))stagingHandler
|
||||
completionHandler:(void(^)(NSDictionary *result))completionHandler
|
||||
{
|
||||
NSString *type = [FBSDKTypeUtility stringValue:openGraphObject[@"og:type"]];
|
||||
if (!type) {
|
||||
NSString *message = @"Open Graph objects must contain a og:type value.";
|
||||
NSError *error = [FBSDKShareError requiredArgumentErrorWithName:@"og:type" message:message];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
void(^containerHandler)(NSDictionary *) = ^(NSDictionary *stagedContainer) {
|
||||
NSError *JSONError;
|
||||
NSString *objectString = [FBSDKInternalUtility JSONStringForObject:stagedContainer
|
||||
error:&JSONError
|
||||
invalidObjectHandler:NULL];
|
||||
if (!objectString) {
|
||||
[_delegate sharer:self didFailWithError:JSONError];
|
||||
return;
|
||||
}
|
||||
NSString *tokenString = [FBSDKAccessToken currentAccessToken].tokenString;
|
||||
NSString *graphPath = [self _graphPathWithSuffix:@"objects", type, nil];
|
||||
NSDictionary *parameters = @{ @"object": objectString };
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath
|
||||
parameters:parameters
|
||||
tokenString:tokenString
|
||||
version:nil
|
||||
HTTPMethod:@"POST"];
|
||||
FBSDKGraphRequestHandler requestCompletionHandler = ^(FBSDKGraphRequestConnection *requestConnection,
|
||||
id result,
|
||||
NSError *requestError) {
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
if (requestError) {
|
||||
NSString *message = [[NSString alloc] initWithFormat:@"Error creating Open Graph object: %@",
|
||||
requestError.description];
|
||||
NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode
|
||||
message:message
|
||||
underlyingError:requestError];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
} else if (completionHandler != NULL) {
|
||||
completionHandler([FBSDKTypeUtility dictionaryValue:result]);
|
||||
}
|
||||
};
|
||||
NSString *batchEntryName = [self _connection:connection
|
||||
addRequest:request
|
||||
completionHandler:requestCompletionHandler];
|
||||
if (stagingHandler != NULL) {
|
||||
stagingHandler([[NSString alloc] initWithFormat:@"{result=%@:$.id}", batchEntryName]);
|
||||
}
|
||||
};
|
||||
return [self _stageOpenGraphValueContainer:openGraphObject connection:connection stagingHandler:containerHandler];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_stageOpenGraphValueContainer:(id<FBSDKShareOpenGraphValueContaining>)container
|
||||
connection:(FBSDKGraphRequestConnection *)connection
|
||||
stagingHandler:(void(^)(NSDictionary *stagedContainer))stagingHandler
|
||||
{
|
||||
__block BOOL result = YES;
|
||||
__block NSUInteger pendingCount = 1;
|
||||
NSMutableDictionary *stagedContainer = [[NSMutableDictionary alloc] init];
|
||||
void(^itemDidFail)(void) = ^{
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
result = NO;
|
||||
};
|
||||
void(^itemDidSucceed)(void) = ^{
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
if ((--pendingCount == 0) && (stagingHandler != NULL)) {
|
||||
stagingHandler(stagedContainer);
|
||||
}
|
||||
};
|
||||
BOOL isAction = [container isKindOfClass:[FBSDKShareOpenGraphAction class]];
|
||||
[container enumerateKeysAndObjectsUsingBlock:^(NSString *key, id object, BOOL *stop) {
|
||||
pendingCount++;
|
||||
|
||||
// The server does not understand custom namespaces remove them until the server is fixed
|
||||
NSString *namespace;
|
||||
key = [FBSDKShareUtility getOpenGraphNameAndNamespaceFromFullName:key namespace:&namespace];
|
||||
if (namespace && !isAction) {
|
||||
if (!stagedContainer[namespace]) {
|
||||
stagedContainer[namespace] = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
void(^itemHandler)(id) = ^(id stagedValue) {
|
||||
if (stagedValue) {
|
||||
if (isAction) {
|
||||
NSError *error;
|
||||
if (![self _addEncodedParametersToDictionary:stagedContainer key:key value:stagedValue error:&error]) {
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
itemDidFail();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
NSMutableDictionary *valueContainer = (namespace ? stagedContainer[namespace] : stagedContainer);
|
||||
valueContainer[key] = stagedValue;
|
||||
}
|
||||
}
|
||||
itemDidSucceed();
|
||||
};
|
||||
if (![self _stageValue:object connection:connection stagingHandler:itemHandler]) {
|
||||
*stop = YES;
|
||||
result = NO;
|
||||
}
|
||||
}];
|
||||
if (result) {
|
||||
itemDidSucceed();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (BOOL)_stagePhoto:(FBSDKSharePhoto *)photo
|
||||
connection:(FBSDKGraphRequestConnection *)connection
|
||||
stagingHandler:(void(^)(id stagedPhoto))stagingHandler
|
||||
{
|
||||
if (photo.imageURL) {
|
||||
NSMutableDictionary *stagedPhoto = [[NSMutableDictionary alloc]initWithDictionary: @{
|
||||
@"url": photo.imageURL.absoluteString,
|
||||
@"user_generated": @(photo.userGenerated),
|
||||
}];
|
||||
[FBSDKInternalUtility dictionary:stagedPhoto setObject:photo.caption forKey:@"caption"];
|
||||
if (stagingHandler) {
|
||||
stagingHandler(stagedPhoto);
|
||||
}
|
||||
return YES;
|
||||
} else if (photo.image) {
|
||||
NSString *graphPath = @"/me/staging_resources";
|
||||
NSDictionary *parameters = @{ @"file": photo.image };
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath
|
||||
parameters:parameters
|
||||
HTTPMethod:@"POST"];
|
||||
FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *requestConnection,
|
||||
id result,
|
||||
NSError *requestError) {
|
||||
NSString *stagedPhotoURLString = [FBSDKTypeUtility stringValue:result[@"uri"]];
|
||||
if (requestError || !stagedPhotoURLString) {
|
||||
NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode
|
||||
message:@"Error staging photo"
|
||||
underlyingError:requestError];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
} else if (stagingHandler) {
|
||||
NSMutableDictionary *stagedPhoto = [[NSMutableDictionary alloc] initWithDictionary: @{
|
||||
@"url": stagedPhotoURLString,
|
||||
@"user_generated": @(photo.userGenerated),
|
||||
}];
|
||||
[FBSDKInternalUtility dictionary:stagedPhoto setObject:photo.caption forKey:@"caption"];
|
||||
stagingHandler(stagedPhoto);
|
||||
}
|
||||
};
|
||||
[request startWithCompletionHandler:completionHandler];
|
||||
return YES;
|
||||
} else {
|
||||
NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"photo"
|
||||
value:photo
|
||||
message:@"Photos must have an imageURL or image."];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_stageValue:(id)value
|
||||
connection:(FBSDKGraphRequestConnection *)connection
|
||||
stagingHandler:(void(^)(id stagedValue))stagingHandler
|
||||
{
|
||||
if ([value isKindOfClass:[NSString class]] ||
|
||||
[value isKindOfClass:[NSNumber class]]) {
|
||||
if (stagingHandler != NULL) {
|
||||
stagingHandler(value);
|
||||
}
|
||||
return YES;
|
||||
} else if ([value isKindOfClass:[NSURL class]]) {
|
||||
if (stagingHandler != NULL) {
|
||||
stagingHandler([(NSURL *)value absoluteString]);
|
||||
}
|
||||
return YES;
|
||||
} else if ([value isKindOfClass:[FBSDKSharePhoto class]]) {
|
||||
return [self _stagePhoto:(FBSDKSharePhoto *)value connection:connection stagingHandler:stagingHandler];
|
||||
} else if ([value isKindOfClass:[FBSDKShareOpenGraphObject class]]) {
|
||||
return [self _stageOpenGraphObject:(FBSDKShareOpenGraphObject *)value
|
||||
connection:connection
|
||||
stagingHandler:stagingHandler
|
||||
completionHandler:NULL];
|
||||
} else if ([value isKindOfClass:[NSArray class]]) {
|
||||
return [self _stageArray:(NSArray *)value connection:connection stagingHandler:stagingHandler];
|
||||
} else {
|
||||
NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"value"
|
||||
value:value
|
||||
message:@"Invalid value type found in Open Graph object."];
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)_connection:(FBSDKGraphRequestConnection *)connection
|
||||
addRequest:(FBSDKGraphRequest *)request
|
||||
completionHandler:(FBSDKGraphRequestHandler)completionHandler
|
||||
{
|
||||
NSUInteger requestCount = [connection.requests count];
|
||||
NSString *batchEntryName = [[NSString alloc] initWithFormat:@"request_%lu", (unsigned long)requestCount];
|
||||
[connection addRequest:request completionHandler:completionHandler batchEntryName:batchEntryName];
|
||||
return batchEntryName;
|
||||
}
|
||||
|
||||
- (BOOL)_addToPendingShareAPI
|
||||
{
|
||||
@synchronized(g_pendingFBSDKShareAPI) {
|
||||
if ([g_pendingFBSDKShareAPI containsObject:self]) {
|
||||
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"FBSDKShareAPI did not share video content. Video upload already in progress."];
|
||||
return NO;
|
||||
}
|
||||
[g_pendingFBSDKShareAPI addObject:self];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_removeFromPendingShareAPI
|
||||
{
|
||||
@synchronized(g_pendingFBSDKShareAPI) {
|
||||
[g_pendingFBSDKShareAPI removeObject:self];
|
||||
_fileHandle = nil;
|
||||
#if !TARGET_OS_TV
|
||||
_assetRepresentation = nil;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKVideoUploaderDelegate
|
||||
|
||||
- (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader startOffset:(NSUInteger)startOffset endOffset:(NSUInteger)endOffset
|
||||
{
|
||||
NSUInteger chunkSize = endOffset - startOffset;
|
||||
if (_fileHandle) {
|
||||
[_fileHandle seekToFileOffset:startOffset];
|
||||
NSData *videoChunkData = [_fileHandle readDataOfLength:chunkSize];
|
||||
if (videoChunkData == nil || videoChunkData.length != chunkSize) {
|
||||
return nil;
|
||||
}
|
||||
return videoChunkData;
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
else if (_assetRepresentation) {
|
||||
NSMutableData *data = [NSMutableData dataWithLength:chunkSize];
|
||||
NSError *error;
|
||||
NSUInteger bufferedLength = [_assetRepresentation getBytes:[data mutableBytes] fromOffset:startOffset length:chunkSize error:&error];
|
||||
if (bufferedLength != chunkSize || data == nil || error) {
|
||||
return nil;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
results = [FBSDKTypeUtility dictionaryValue:results];
|
||||
NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
[FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:results[FBSDK_SHARE_VIDEO_ID]] forKey:FBSDK_SHARE_VIDEO_ID];
|
||||
[_delegate sharer:self didCompleteWithResults:shareResults];
|
||||
[self _removeFromPendingShareAPI];
|
||||
}
|
||||
|
||||
- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didFailWithError:(NSError *)error
|
||||
{
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
[self _removeFromPendingShareAPI];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKButton.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharingButton.h>
|
||||
|
||||
/*!
|
||||
@abstract A button to share content.
|
||||
@discussion Tapping the receiver will invoke the FBSDKShareDialog with the attached shareContent. If the dialog cannot
|
||||
be shown, the button will be disabled.
|
||||
*/
|
||||
@interface FBSDKShareButton : FBSDKButton <FBSDKSharingButton>
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareButton.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareDialog.h"
|
||||
|
||||
@implementation FBSDKShareButton
|
||||
{
|
||||
FBSDKShareDialog *_dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (id<FBSDKSharingContent>)shareContent
|
||||
{
|
||||
return _dialog.shareContent;
|
||||
}
|
||||
|
||||
- (void)setShareContent:(id<FBSDKSharingContent>)shareContent
|
||||
{
|
||||
_dialog.shareContent = shareContent;
|
||||
[self checkImplicitlyDisabled];
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKButtonImpressionTracking
|
||||
|
||||
- (NSDictionary *)analyticsParameters
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *)impressionTrackingEventName
|
||||
{
|
||||
return FBSDKAppEventNameFBSDKShareButtonImpression;
|
||||
}
|
||||
|
||||
- (NSString *)impressionTrackingIdentifier
|
||||
{
|
||||
return @"share";
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKButton
|
||||
|
||||
- (void)configureButton
|
||||
{
|
||||
NSString *title =
|
||||
NSLocalizedStringWithDefaultValue(@"ShareButton.Share", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings],
|
||||
@"Share",
|
||||
@"The label for FBSDKShareButton");
|
||||
|
||||
[self configureWithIcon:nil
|
||||
title:title
|
||||
backgroundColor:nil
|
||||
highlightedColor:nil];
|
||||
|
||||
[self addTarget:self action:@selector(_share:) forControlEvents:UIControlEventTouchUpInside];
|
||||
_dialog = [[FBSDKShareDialog alloc] init];
|
||||
}
|
||||
|
||||
- (BOOL)isImplicitlyDisabled
|
||||
{
|
||||
return ![_dialog canShow] || ![_dialog validateWithError:NULL];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_share:(id)sender
|
||||
{
|
||||
[self logTapEventWithEventName:FBSDKAppEventNameFBSDKShareButtonDidTap parameters:[self analyticsParameters]];
|
||||
[_dialog show];
|
||||
}
|
||||
|
||||
@end
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
|
||||
/*!
|
||||
@abstract The error domain for all errors from FBSDKShareKit.
|
||||
@discussion Error codes from the SDK in the range 200-299 are reserved for this domain.
|
||||
*/
|
||||
FBSDK_EXTERN NSString *const FBSDKShareErrorDomain;
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM(NSInteger, FBSDKShareErrorCode)
|
||||
@abstract Error codes for FBSDKShareErrorDomain.
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, FBSDKShareErrorCode)
|
||||
{
|
||||
/*!
|
||||
@abstract Reserved.
|
||||
*/
|
||||
FBSDKShareReservedErrorCode = 200,
|
||||
|
||||
/*!
|
||||
@abstract The error code for errors from uploading open graph objects.
|
||||
*/
|
||||
FBSDKShareOpenGraphErrorCode,
|
||||
|
||||
/*!
|
||||
@abstract The error code for when a sharing dialog is not available.
|
||||
@discussion Use the canShare methods to check for this case before calling show.
|
||||
*/
|
||||
FBSDKShareDialogNotAvailableErrorCode,
|
||||
|
||||
/*!
|
||||
@The error code for unknown errors.
|
||||
*/
|
||||
FBSDKShareUnknownErrorCode,
|
||||
};
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareConstants.h"
|
||||
|
||||
NSString *const FBSDKShareErrorDomain = @"com.facebook.sdk.share";
|
||||
|
||||
NSString *const FBSDKShareOpenGraphKeyErrorKey = @"key";
|
||||
NSString *const FBSDKShareOpenGraphValueErrorKey = @"value";
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareDialogMode.h>
|
||||
#import <FBSDKShareKit/FBSDKSharing.h>
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
/*!
|
||||
@abstract A dialog for sharing content on Facebook.
|
||||
*/
|
||||
@interface FBSDKShareDialog : NSObject <FBSDKSharingDialog>
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to show an FBSDKShareDialog with a fromViewController, content and a delegate.
|
||||
@param viewController A UIViewController to present the dialog from, if appropriate.
|
||||
@param content The content to be shared.
|
||||
@param delegate The receiver's delegate.
|
||||
*/
|
||||
+ (instancetype)showFromViewController:(UIViewController *)viewController
|
||||
withContent:(id<FBSDKSharingContent>)content
|
||||
delegate:(id<FBSDKSharingDelegate>)delegate;
|
||||
|
||||
/*!
|
||||
@abstract A UIViewController to present the dialog from.
|
||||
@discussion If not specified, the top most view controller will be automatically determined as best as possible.
|
||||
*/
|
||||
@property (nonatomic, weak) UIViewController *fromViewController;
|
||||
|
||||
/*!
|
||||
@abstract The mode with which to display the dialog.
|
||||
@discussion Defaults to FBSDKShareDialogModeAutomatic, which will automatically choose the best available mode.
|
||||
*/
|
||||
@property (nonatomic, assign) FBSDKShareDialogMode mode;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,788 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareDialog.h"
|
||||
|
||||
#import <Social/Social.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareDefines.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareLinkContent.h"
|
||||
#import "FBSDKShareOpenGraphAction.h"
|
||||
#import "FBSDKShareOpenGraphContent.h"
|
||||
#import "FBSDKShareOpenGraphObject.h"
|
||||
#import "FBSDKSharePhoto.h"
|
||||
#import "FBSDKSharePhotoContent.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
#import "FBSDKShareVideo.h"
|
||||
#import "FBSDKShareVideoContent.h"
|
||||
|
||||
#define FBSDK_SHARE_DIALOG_APP_SCHEME @"fbapi"
|
||||
#define FBSDK_SHARE_EXTENSION_APP_SCHEME @"fbshareextension"
|
||||
#define FBSDK_SHARE_FEED_METHOD_NAME @"feed"
|
||||
#define FBSDK_SHARE_METHOD_MIN_VERSION @"20130410"
|
||||
#define FBSDK_SHARE_METHOD_OG_MIN_VERSION @"20130214"
|
||||
#define FBSDK_SHARE_METHOD_OG_IMAGE_MIN_VERSION @"20130410"
|
||||
#define FBSDK_SHARE_METHOD_PHOTOS_MIN_VERSION @"20140116"
|
||||
#define FBSDK_SHARE_METHOD_VIDEO_MIN_VERSION @"20150313"
|
||||
#define FBSDK_SHARE_METHOD_ATTRIBUTED_SHARE_SHEET_MIN_VERSION @"20150629"
|
||||
|
||||
@interface FBSDKShareDialog () <FBSDKWebDialogDelegate>
|
||||
@end
|
||||
|
||||
@implementation FBSDKShareDialog
|
||||
{
|
||||
FBSDKWebDialog *_webDialog;
|
||||
}
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if ([FBSDKShareDialog class] == self) {
|
||||
[FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK];
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
+ (instancetype)showFromViewController:(UIViewController *)viewController
|
||||
withContent:(id<FBSDKSharingContent>)content
|
||||
delegate:(id<FBSDKSharingDelegate>)delegate
|
||||
{
|
||||
FBSDKShareDialog *dialog = [[self alloc] init];
|
||||
dialog.fromViewController = viewController;
|
||||
dialog.shareContent = content;
|
||||
dialog.delegate = delegate;
|
||||
[dialog show];
|
||||
return dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_webDialog.delegate = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
@synthesize shareContent = _shareContent;
|
||||
@synthesize shouldFailOnDataError = _shouldFailOnDataError;
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canShow
|
||||
{
|
||||
switch (self.mode) {
|
||||
case FBSDKShareDialogModeAutomatic:
|
||||
case FBSDKShareDialogModeBrowser:
|
||||
case FBSDKShareDialogModeFeedBrowser:
|
||||
case FBSDKShareDialogModeFeedWeb:
|
||||
case FBSDKShareDialogModeWeb:{
|
||||
return YES;
|
||||
}
|
||||
case FBSDKShareDialogModeNative:{
|
||||
return [self _canShowNative];
|
||||
}
|
||||
case FBSDKShareDialogModeShareSheet:{
|
||||
return [self _canShowShareSheet];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)show
|
||||
{
|
||||
BOOL didShow = NO;
|
||||
NSError *error = nil;
|
||||
|
||||
if ([self validateWithError:&error]) {
|
||||
switch (self.mode) {
|
||||
case FBSDKShareDialogModeAutomatic:{
|
||||
didShow = [self _showAutomatic:&error];
|
||||
break;
|
||||
}
|
||||
case FBSDKShareDialogModeBrowser:{
|
||||
didShow = [self _showBrowser:&error];
|
||||
break;
|
||||
}
|
||||
case FBSDKShareDialogModeFeedBrowser:{
|
||||
didShow = [self _showFeedBrowser:&error];
|
||||
break;
|
||||
}
|
||||
case FBSDKShareDialogModeFeedWeb:{
|
||||
didShow = [self _showFeedWeb:&error];
|
||||
break;
|
||||
}
|
||||
case FBSDKShareDialogModeNative:{
|
||||
didShow = [self _showNativeWithCanShowError:&error validationError:&error];
|
||||
break;
|
||||
}
|
||||
case FBSDKShareDialogModeShareSheet:{
|
||||
didShow = [self _showShareSheetWithCanShowError:&error validationError:&error];
|
||||
break;
|
||||
}
|
||||
case FBSDKShareDialogModeWeb:{
|
||||
didShow = [self _showWeb:&error];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!didShow) {
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
} else {
|
||||
[self _logDialogShow];
|
||||
[FBSDKInternalUtility registerTransientObject:self];
|
||||
}
|
||||
return didShow;
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if (!shareContent) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (![FBSDKShareUtility validateShareContent:shareContent error:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
if (![FBSDKShareUtility validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)shareContent name:@"videoURL" error:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
switch (self.mode) {
|
||||
case FBSDKShareDialogModeAutomatic:{
|
||||
return (
|
||||
([self _canShowNative] && [self _validateShareContentForNative:errorRef]) ||
|
||||
([self _canShowShareSheet] && [self _validateShareContentForShareSheet:errorRef]) ||
|
||||
[self _validateShareContentForFeed:errorRef] ||
|
||||
[self _validateShareContentForBrowser:errorRef]);
|
||||
}
|
||||
case FBSDKShareDialogModeNative:{
|
||||
return [self _validateShareContentForNative:errorRef];
|
||||
}
|
||||
case FBSDKShareDialogModeShareSheet:{
|
||||
return [self _validateShareContentForShareSheet:errorRef];
|
||||
}
|
||||
case FBSDKShareDialogModeBrowser:
|
||||
case FBSDKShareDialogModeWeb:{
|
||||
return [self _validateShareContentForBrowser:errorRef];
|
||||
}
|
||||
case FBSDKShareDialogModeFeedBrowser:
|
||||
case FBSDKShareDialogModeFeedWeb:{
|
||||
return [self _validateShareContentForFeed:errorRef];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - FBSDKWebDialogDelegate
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[self _cleanUpWebDialog];
|
||||
NSInteger errorCode = [results[@"error_code"] integerValue];
|
||||
if (errorCode == 4201) {
|
||||
[self _invokeDelegateDidCancel];
|
||||
} else {
|
||||
// not all web dialogs report cancellation, so assume that the share has completed with no additional information
|
||||
[self _handleWebResponseParameters:results error:nil];
|
||||
}
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[self _cleanUpWebDialog];
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
- (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog
|
||||
{
|
||||
if (_webDialog != webDialog) {
|
||||
return;
|
||||
}
|
||||
[self _cleanUpWebDialog];
|
||||
[self _invokeDelegateDidCancel];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
-(BOOL)_isDefaultToShareSheet
|
||||
{
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
return [configuration.defaultShareMode isEqualToString:@"share_sheet"];
|
||||
}
|
||||
|
||||
-(BOOL)_showAutomatic:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
BOOL isDefaultToShareSheet = [self _isDefaultToShareSheet];
|
||||
BOOL useNativeDialog = [self _useNativeDialog];
|
||||
return ((isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) ||
|
||||
(useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef]) ||
|
||||
(!isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) ||
|
||||
[self _showFeedBrowser:errorRef] ||
|
||||
[self _showFeedWeb:errorRef] ||
|
||||
[self _showBrowser:errorRef] ||
|
||||
[self _showWeb:errorRef] ||
|
||||
(!useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef]));
|
||||
}
|
||||
|
||||
- (void)_loadNativeMethodName:(NSString **)methodNameRef methodVersion:(NSString **)methodVersionRef
|
||||
{
|
||||
if (methodNameRef != NULL) {
|
||||
*methodNameRef = nil;
|
||||
}
|
||||
if (methodVersionRef != NULL) {
|
||||
*methodVersionRef = nil;
|
||||
}
|
||||
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if (!shareContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is shareContent on the receiver already, we can check the minimum app version, otherwise we can only check
|
||||
// for an app that can handle the native share dialog
|
||||
NSString *methodName = nil;
|
||||
NSString *methodVersion = nil;
|
||||
if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
methodName = FBSDK_SHARE_OPEN_GRAPH_METHOD_NAME;
|
||||
BOOL containsMedia = NO;
|
||||
[FBSDKShareUtility testShareContent:shareContent containsMedia:&containsMedia containsPhotos:NULL];
|
||||
if (containsMedia) {
|
||||
methodVersion = FBSDK_SHARE_METHOD_OG_IMAGE_MIN_VERSION;
|
||||
} else {
|
||||
methodVersion = FBSDK_SHARE_METHOD_OG_MIN_VERSION;
|
||||
}
|
||||
} else {
|
||||
methodName = FBSDK_SHARE_METHOD_NAME;
|
||||
if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
methodVersion = FBSDK_SHARE_METHOD_PHOTOS_MIN_VERSION;
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
methodVersion = FBSDK_SHARE_METHOD_VIDEO_MIN_VERSION;
|
||||
} else {
|
||||
methodVersion = FBSDK_SHARE_METHOD_MIN_VERSION;
|
||||
}
|
||||
}
|
||||
if (methodNameRef != NULL) {
|
||||
*methodNameRef = methodName;
|
||||
}
|
||||
if (methodVersionRef != NULL) {
|
||||
*methodVersionRef = methodVersion;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_canShowNative
|
||||
{
|
||||
return [FBSDKInternalUtility isFacebookAppInstalled];
|
||||
}
|
||||
|
||||
- (BOOL)_canShowShareSheet
|
||||
{
|
||||
Class composeViewControllerClass = [fbsdkdfl_SLComposeViewControllerClass() class];
|
||||
if (!composeViewControllerClass) {
|
||||
return NO;
|
||||
}
|
||||
NSString *facebookServiceType = fbsdkdfl_SLServiceTypeFacebook();
|
||||
if (![composeViewControllerClass isAvailableForServiceType:facebookServiceType]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_canAttributeThroughShareSheet
|
||||
{
|
||||
NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 };
|
||||
if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) {
|
||||
return NO;
|
||||
}
|
||||
NSString *scheme = FBSDK_SHARE_DIALOG_APP_SCHEME;
|
||||
NSString *minimumVersion = FBSDK_SHARE_METHOD_ATTRIBUTED_SHARE_SHEET_MIN_VERSION;
|
||||
NSURLComponents *components = [[NSURLComponents alloc] init];
|
||||
components.scheme = [scheme stringByAppendingString:minimumVersion];
|
||||
components.path = @"/";
|
||||
return ([[UIApplication sharedApplication] canOpenURL:components.URL] ||
|
||||
[self _canUseFBShareSheet]);
|
||||
}
|
||||
|
||||
- (BOOL)_canUseFBShareSheet
|
||||
{
|
||||
NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 };
|
||||
if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) {
|
||||
return NO;
|
||||
}
|
||||
NSURLComponents *components = [[NSURLComponents alloc] init];
|
||||
components.scheme = FBSDK_SHARE_EXTENSION_APP_SCHEME;
|
||||
components.path = @"/";
|
||||
return [[UIApplication sharedApplication] canOpenURL:components.URL];
|
||||
}
|
||||
|
||||
- (void)_cleanUpWebDialog
|
||||
{
|
||||
_webDialog.delegate = nil;
|
||||
_webDialog = nil;
|
||||
}
|
||||
|
||||
- (NSArray *)_contentImages
|
||||
{
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
return ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]] ?
|
||||
[((FBSDKSharePhotoContent *)shareContent).photos valueForKeyPath:@"@distinctUnionOfObjects.image"] :
|
||||
nil);
|
||||
}
|
||||
|
||||
- (NSArray *)_contentURLs
|
||||
{
|
||||
NSArray *URLs = nil;
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
FBSDKShareLinkContent *linkContent = (FBSDKShareLinkContent *)shareContent;
|
||||
URLs = (linkContent.contentURL ? @[linkContent.contentURL] : nil);
|
||||
} else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
FBSDKSharePhotoContent *photoContent = (FBSDKSharePhotoContent *)shareContent;
|
||||
URLs = (photoContent.contentURL ? @[photoContent.contentURL] : nil);
|
||||
}
|
||||
return URLs;
|
||||
}
|
||||
|
||||
- (void)_handleWebResponseParameters:(NSDictionary *)webResponseParameters error:(NSError *)error
|
||||
{
|
||||
if (error) {
|
||||
[self _invokeDelegateDidFailWithError:error];
|
||||
return;
|
||||
} else {
|
||||
NSString *completionGesture = webResponseParameters[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL]) {
|
||||
[self _invokeDelegateDidCancel];
|
||||
} else {
|
||||
// not all web dialogs report cancellation, so assume that the share has completed with no additional information
|
||||
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
|
||||
// the web response comes back with a different payload, so we need to translate it
|
||||
[FBSDKInternalUtility dictionary:results
|
||||
setObject:webResponseParameters[FBSDK_SHARE_WEB_PARAM_POST_ID_KEY]
|
||||
forKey:FBSDK_SHARE_RESULT_POST_ID_KEY];
|
||||
[self _invokeDelegateDidCompleteWithResults:results];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_showBrowser:(NSError **)errorRef
|
||||
{
|
||||
if (![self _validateShareContentForBrowser:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
NSString *methodName;
|
||||
NSDictionary *parameters;
|
||||
if (![FBSDKShareUtility buildWebShareContent:shareContent
|
||||
methodName:&methodName
|
||||
parameters:¶meters
|
||||
error:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) {
|
||||
[self _handleWebResponseParameters:response.responseParameters error:response.error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
};
|
||||
FBSDKBridgeAPIRequest *request;
|
||||
request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb
|
||||
scheme:FBSDK_SHARE_WEB_SCHEME
|
||||
methodName:methodName
|
||||
methodVersion:nil
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request
|
||||
useSafariViewController:[self _useSafariViewController]
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:completionBlock];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_showFeedBrowser:(NSError **)errorRef
|
||||
{
|
||||
if (![self _validateShareContentForFeed:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
NSDictionary *parameters = [FBSDKShareUtility feedShareDictionaryForContent:shareContent];
|
||||
FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) {
|
||||
[self _handleWebResponseParameters:response.responseParameters error:response.error];
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
};
|
||||
FBSDKBridgeAPIRequest *request;
|
||||
request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb
|
||||
scheme:FBSDK_SHARE_WEB_SCHEME
|
||||
methodName:FBSDK_SHARE_FEED_METHOD_NAME
|
||||
methodVersion:nil
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request
|
||||
useSafariViewController:[self _useSafariViewController]
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:completionBlock];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_showFeedWeb:(NSError **)errorRef
|
||||
{
|
||||
if (![self _validateShareContentForFeed:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
NSDictionary *parameters = [FBSDKShareUtility feedShareDictionaryForContent:shareContent];
|
||||
_webDialog = [FBSDKWebDialog showWithName:FBSDK_SHARE_FEED_METHOD_NAME
|
||||
parameters:parameters
|
||||
delegate:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_showNativeWithCanShowError:(NSError **)canShowErrorRef validationError:(NSError **)validationErrorRef
|
||||
{
|
||||
if (![self _canShowNative]) {
|
||||
if (canShowErrorRef != NULL) {
|
||||
*canShowErrorRef = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"Native share dialog is not available."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (![self _validateShareContentForNative:validationErrorRef]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString *methodName;
|
||||
NSString *methodVersion;
|
||||
[self _loadNativeMethodName:&methodName methodVersion:&methodVersion];
|
||||
NSDictionary *parameters = [FBSDKShareUtility parametersForShareContent:self.shareContent
|
||||
shouldFailOnDataError:self.shouldFailOnDataError];
|
||||
FBSDKBridgeAPIRequest *request;
|
||||
request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative
|
||||
scheme:FBSDK_CANOPENURL_FACEBOOK
|
||||
methodName:methodName
|
||||
methodVersion:methodVersion
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) {
|
||||
if (response.error.code == FBSDKAppVersionUnsupportedErrorCode) {
|
||||
NSError *fallbackError;
|
||||
if ([self _showShareSheetWithCanShowError:NULL validationError:&fallbackError] ||
|
||||
[self _showFeedBrowser:&fallbackError]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
NSDictionary *responseParameters = response.responseParameters;
|
||||
NSString *completionGesture = responseParameters[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL] ||
|
||||
response.isCancelled) {
|
||||
[self _invokeDelegateDidCancel];
|
||||
} else if (response.error) {
|
||||
[self _invokeDelegateDidFailWithError:response.error];
|
||||
} else {
|
||||
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:results
|
||||
setObject:responseParameters[FBSDK_SHARE_RESULT_POST_ID_KEY]
|
||||
forKey:FBSDK_SHARE_RESULT_POST_ID_KEY];
|
||||
[self _invokeDelegateDidCompleteWithResults:results];
|
||||
}
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
};
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request
|
||||
useSafariViewController:[self _useSafariViewController]
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:completionBlock];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_showShareSheetWithCanShowError:(NSError **)canShowErrorRef validationError:(NSError **)validationErrorRef
|
||||
{
|
||||
if (![self _canShowShareSheet]) {
|
||||
if (canShowErrorRef != NULL) {
|
||||
*canShowErrorRef = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"Share sheet is not available."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (![self _validateShareContentForShareSheet:validationErrorRef]) {
|
||||
return NO;
|
||||
}
|
||||
UIViewController *fromViewController = self.fromViewController;
|
||||
if (!fromViewController) {
|
||||
if (validationErrorRef != NULL) {
|
||||
*validationErrorRef = [FBSDKShareError requiredArgumentErrorWithName:@"fromViewController" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
NSArray *images = [self _contentImages];
|
||||
NSArray *URLs = [self _contentURLs];
|
||||
NSURL *videoURL = ([self.shareContent isKindOfClass:[FBSDKShareVideoContent class]] ?
|
||||
((FBSDKShareVideoContent *)self.shareContent).video.videoURL :
|
||||
nil);
|
||||
|
||||
Class composeViewControllerClass = [fbsdkdfl_SLComposeViewControllerClass() class];
|
||||
NSString *facebookServiceType = fbsdkdfl_SLServiceTypeFacebook();
|
||||
SLComposeViewController *composeViewController;
|
||||
composeViewController = [composeViewControllerClass composeViewControllerForServiceType:facebookServiceType];
|
||||
|
||||
if (!composeViewController) {
|
||||
if (canShowErrorRef != NULL) {
|
||||
*canShowErrorRef = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"Error creating SLComposeViewController."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if ([self _canAttributeThroughShareSheet]) {
|
||||
NSString *attributionToken = [NSString stringWithFormat:@"fb-app-id:%@", [FBSDKSettings appID]];
|
||||
[composeViewController setInitialText:attributionToken];
|
||||
}
|
||||
for (UIImage *image in images) {
|
||||
[composeViewController addImage:image];
|
||||
}
|
||||
for (NSURL *URL in URLs) {
|
||||
[composeViewController addURL:URL];
|
||||
}
|
||||
if (videoURL) {
|
||||
[composeViewController addURL:videoURL];
|
||||
}
|
||||
composeViewController.completionHandler = ^(SLComposeViewControllerResult result) {
|
||||
switch (result) {
|
||||
case SLComposeViewControllerResultCancelled:{
|
||||
[self _invokeDelegateDidCancel];
|
||||
break;
|
||||
}
|
||||
case SLComposeViewControllerResultDone:{
|
||||
[self _invokeDelegateDidCompleteWithResults:@{}];
|
||||
break;
|
||||
}
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[FBSDKInternalUtility unregisterTransientObject:self];
|
||||
});
|
||||
};
|
||||
[fromViewController presentViewController:composeViewController animated:YES completion:nil];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_showWeb:(NSError **)errorRef
|
||||
{
|
||||
if (![self _validateShareContentForBrowser:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
NSString *methodName;
|
||||
NSDictionary *parameters;
|
||||
if (![FBSDKShareUtility buildWebShareContent:shareContent
|
||||
methodName:&methodName
|
||||
parameters:¶meters
|
||||
error:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
_webDialog = [FBSDKWebDialog showWithName:methodName
|
||||
parameters:parameters
|
||||
delegate:self];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_useNativeDialog
|
||||
{
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
return [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameShare];
|
||||
}
|
||||
|
||||
- (BOOL)_useSafariViewController
|
||||
{
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
return [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameShare];
|
||||
}
|
||||
|
||||
- (BOOL)_validateShareContentForBrowser:(NSError **)errorRef
|
||||
{
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
BOOL containsMedia;
|
||||
BOOL containsPhotos;
|
||||
[FBSDKShareUtility testShareContent:shareContent containsMedia:&containsMedia containsPhotos:&containsPhotos];
|
||||
if (containsPhotos) {
|
||||
if ((errorRef != NULL) && !*errorRef) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
|
||||
value:shareContent
|
||||
message:@"Web share dialogs cannot include photos."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (containsMedia) {
|
||||
if ((errorRef != NULL) && !*errorRef) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
|
||||
value:shareContent
|
||||
message:@"Web share dialogs cannot include local media."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_validateShareContentForFeed:(NSError **)errorRef
|
||||
{
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if (![shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
if ((errorRef != NULL) && !*errorRef) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
|
||||
value:shareContent
|
||||
message:@"Feed share dialogs support FBSDKShareLinkContent."];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_validateShareContentForNative:(NSError **)errorRef
|
||||
{
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if (![shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
return YES;
|
||||
}
|
||||
return [self _validateVideoURL:((FBSDKShareVideoContent *)shareContent).video.videoURL error:errorRef];
|
||||
}
|
||||
|
||||
- (BOOL)_validateShareContentForShareSheet:(NSError **)errorRef
|
||||
{
|
||||
id<FBSDKSharingContent> shareContent = self.shareContent;
|
||||
if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
if ([self _contentImages] != 0) {
|
||||
return YES;
|
||||
} else {
|
||||
if ((errorRef != NULL) && !*errorRef) {
|
||||
NSString *message = @"Share photo content must have UIImage photos in order to share with the share sheet";
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
return ([self _canUseFBShareSheet] &&
|
||||
[self _validateVideoURL:((FBSDKShareVideoContent *)shareContent).video.videoURL error:errorRef]);
|
||||
} else if (![shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
if ((errorRef != NULL) && !*errorRef) {
|
||||
NSString *message = @"Share content must be FBSDKShareLinkContent or FBSDKSharePhotoContent in order to share "
|
||||
@"with the share sheet.";
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)_validateVideoURL:(NSURL *)videoURL error:(NSError **)errorRef
|
||||
{
|
||||
if (videoURL.isFileURL) {
|
||||
if ((errorRef != NULL) && !*errorRef) {
|
||||
NSString *message = @"Only asset file URLs are allowed for videos.";
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"videoURL" value:videoURL message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidCancel
|
||||
{
|
||||
NSDictionary * parameters = @{
|
||||
FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Cancelled,
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDLAppEventNameFBSDKEventShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
[_delegate sharerDidCancel:self];
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results
|
||||
{
|
||||
NSDictionary * parameters = @{
|
||||
FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDLAppEventNameFBSDKEventShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
[_delegate sharer:self didCompleteWithResults:[results copy]];
|
||||
}
|
||||
|
||||
- (void)_invokeDelegateDidFailWithError:(NSError *)error
|
||||
{
|
||||
NSDictionary * parameters = @{
|
||||
FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Failed,
|
||||
FBSDKAppEventParameterDialogErrorMessage : [NSString stringWithFormat:@"%@", error]
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDLAppEventNameFBSDKEventShareDialogResult
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
|
||||
[_delegate sharer:self didFailWithError:error];
|
||||
}
|
||||
|
||||
- (void)_logDialogShow
|
||||
{
|
||||
NSString *shareMode = NSStringFromFBSDKShareDialogMode(self.mode);
|
||||
|
||||
NSString *contentType;
|
||||
if([self.shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeOpenGraph;
|
||||
} else if ([self.shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeStatus;
|
||||
} else if ([self.shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypePhoto;
|
||||
} else if ([self.shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeVideo;
|
||||
} else {
|
||||
contentType = FBSDKAppEventsDialogShareContentTypeUnknown;
|
||||
}
|
||||
|
||||
|
||||
NSDictionary *parameters = @{
|
||||
FBSDKAppEventParameterDialogMode : shareMode,
|
||||
FBSDKAppEventParameterDialogShareContentType : contentType,
|
||||
|
||||
};
|
||||
|
||||
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventShareDialogShow
|
||||
valueToSum:nil
|
||||
parameters:parameters
|
||||
accessToken:[FBSDKAccessToken currentAccessToken]];
|
||||
}
|
||||
|
||||
@end
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM(NSUInteger, FBSDKShareDialogMode)
|
||||
@abstract Modes for the FBSDKShareDialog.
|
||||
@discussion The automatic mode will progressively check the availability of different modes and open the most
|
||||
appropriate mode for the dialog that is available.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKShareDialogMode)
|
||||
{
|
||||
/*!
|
||||
@abstract Acts with the most appropriate mode that is available.
|
||||
*/
|
||||
FBSDKShareDialogModeAutomatic = 0,
|
||||
/*!
|
||||
@Displays the dialog in the main native Facebook app.
|
||||
*/
|
||||
FBSDKShareDialogModeNative,
|
||||
/*!
|
||||
@Displays the dialog in the iOS integrated share sheet.
|
||||
*/
|
||||
FBSDKShareDialogModeShareSheet,
|
||||
/*!
|
||||
@Displays the dialog in Safari.
|
||||
*/
|
||||
FBSDKShareDialogModeBrowser,
|
||||
/*!
|
||||
@Displays the dialog in a UIWebView within the app.
|
||||
*/
|
||||
FBSDKShareDialogModeWeb,
|
||||
/*!
|
||||
@Displays the feed dialog in Safari.
|
||||
*/
|
||||
FBSDKShareDialogModeFeedBrowser,
|
||||
/*!
|
||||
@Displays the feed dialog in a UIWebView within the app.
|
||||
*/
|
||||
FBSDKShareDialogModeFeedWeb,
|
||||
};
|
||||
|
||||
/*!
|
||||
@abstract Converts an FBLikeControlObjectType to an NSString.
|
||||
*/
|
||||
FBSDK_EXTERN NSString *NSStringFromFBSDKShareDialogMode(FBSDKShareDialogMode dialogMode);
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareDialogMode.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
NSString *NSStringFromFBSDKShareDialogMode(FBSDKShareDialogMode dialogMode)
|
||||
{
|
||||
switch (dialogMode) {
|
||||
case FBSDKShareDialogModeAutomatic:{
|
||||
return FBSDKAppEventsDialogShareModeAutomatic;
|
||||
}
|
||||
case FBSDKShareDialogModeBrowser:{
|
||||
return FBSDKAppEventsDialogShareModeBrowser;
|
||||
}
|
||||
case FBSDKShareDialogModeNative:{
|
||||
return FBSDKAppEventsDialogShareModeNative;
|
||||
}
|
||||
case FBSDKShareDialogModeShareSheet:{
|
||||
return FBSDKAppEventsDialogShareModeShareSheet;
|
||||
}
|
||||
case FBSDKShareDialogModeWeb:{
|
||||
return FBSDKAppEventsDialogShareModeWeb;
|
||||
}
|
||||
case FBSDKShareDialogModeFeedBrowser: {
|
||||
return FBSDKAppEventsDialogShareModeFeedBrowser;
|
||||
}
|
||||
case FBSDKShareDialogModeFeedWeb:{
|
||||
return FBSDKAppEventsDialogShareModeFeedWeb;
|
||||
}
|
||||
default:{
|
||||
return FBSDKAppEventsDialogShareModeUnknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareAPI.h>
|
||||
#import <FBSDKShareKit/FBSDKShareConstants.h>
|
||||
#import <FBSDKShareKit/FBSDKShareLinkContent.h>
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphAction.h>
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphContent.h>
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphObject.h>
|
||||
#import <FBSDKShareKit/FBSDKSharePhoto.h>
|
||||
#import <FBSDKShareKit/FBSDKSharePhotoContent.h>
|
||||
#import <FBSDKShareKit/FBSDKShareVideo.h>
|
||||
#import <FBSDKShareKit/FBSDKShareVideoContent.h>
|
||||
#import <FBSDKShareKit/FBSDKSharing.h>
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#import <FBSDKShareKit/FBSDKAppGroupAddDialog.h>
|
||||
#import <FBSDKShareKit/FBSDKAppGroupContent.h>
|
||||
#import <FBSDKShareKit/FBSDKAppGroupJoinDialog.h>
|
||||
#import <FBSDKShareKit/FBSDKAppInviteContent.h>
|
||||
#import <FBSDKShareKit/FBSDKAppInviteDialog.h>
|
||||
#import <FBSDKShareKit/FBSDKGameRequestContent.h>
|
||||
#import <FBSDKShareKit/FBSDKGameRequestDialog.h>
|
||||
#import <FBSDKShareKit/FBSDKLikeButton.h>
|
||||
#import <FBSDKShareKit/FBSDKLikeControl.h>
|
||||
#import <FBSDKShareKit/FBSDKLikeObjectType.h>
|
||||
#import <FBSDKShareKit/FBSDKMessageDialog.h>
|
||||
#import <FBSDKShareKit/FBSDKShareButton.h>
|
||||
#import <FBSDKShareKit/FBSDKShareDialog.h>
|
||||
#import <FBSDKShareKit/FBSDKShareDialogMode.h>
|
||||
#import <FBSDKShareKit/FBSDKSendButton.h>
|
||||
#endif
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
/*!
|
||||
@abstract A model for status and link content to be shared.
|
||||
*/
|
||||
@interface FBSDKShareLinkContent : NSObject <FBSDKSharingContent>
|
||||
|
||||
/*!
|
||||
@abstract The description of the link.
|
||||
@discussion If not specified, this field is automatically populated by information scraped from the contentURL,
|
||||
typically the title of the page. This value may be discarded for specially handled links (ex: iTunes URLs).
|
||||
@return The description of the link
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *contentDescription;
|
||||
|
||||
/*!
|
||||
@abstract The title to display for this link.
|
||||
@discussion This value may be discarded for specially handled links (ex: iTunes URLs).
|
||||
@return The link title
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *contentTitle;
|
||||
|
||||
/*!
|
||||
@abstract The URL of a picture to attach to this content.
|
||||
@return The network URL of an image
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL *imageURL;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another link content.
|
||||
@param content The other content
|
||||
@return YES if the receiver's values are equal to the other content's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToShareLinkContent:(FBSDKShareLinkContent *)content;
|
||||
|
||||
@end
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareLinkContent+Internal.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_CONTENT_DESCRIPTION_KEY @"contentDescription"
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_CONTENT_TITLE_KEY @"contentTitle"
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_CONTENT_URL_KEY @"contentURL"
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_IMAGE_URL_KEY @"imageURL"
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_PEOPLE_IDS_KEY @"peopleIDs"
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_PLACE_ID_KEY @"placeID"
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_REF_KEY @"ref"
|
||||
#define FBSDK_SHARE_STATUS_CONTENT_FEED_PARAMETERS_KEY @"feedParameters"
|
||||
|
||||
@implementation FBSDKShareLinkContent
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@synthesize contentURL = _contentURL;
|
||||
@synthesize peopleIDs = _peopleIDs;
|
||||
@synthesize placeID = _placeID;
|
||||
@synthesize ref = _ref;
|
||||
@synthesize feedParameters = _feedParameters;
|
||||
|
||||
- (void)setPeopleIDs:(NSArray *)peopleIDs
|
||||
{
|
||||
[FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"];
|
||||
if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) {
|
||||
_peopleIDs = [peopleIDs copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFeedParameters:(NSDictionary *)feedParameters
|
||||
{
|
||||
if (![_feedParameters isEqualToDictionary:feedParameters]) {
|
||||
_feedParameters = [feedParameters copy];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[_contentDescription hash],
|
||||
[_contentURL hash],
|
||||
[_imageURL hash],
|
||||
[_peopleIDs hash],
|
||||
[_placeID hash],
|
||||
[_ref hash],
|
||||
[_contentTitle hash],
|
||||
[_feedParameters hash],
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToShareLinkContent:(FBSDKShareLinkContent *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToShareLinkContent:(FBSDKShareLinkContent *)content
|
||||
{
|
||||
return (content &&
|
||||
[FBSDKInternalUtility object:_contentDescription isEqualToObject:content.contentDescription] &&
|
||||
[FBSDKInternalUtility object:_contentTitle isEqualToObject:content.contentTitle] &&
|
||||
[FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] &&
|
||||
[FBSDKInternalUtility object:_feedParameters isEqualToObject:content.feedParameters] &&
|
||||
[FBSDKInternalUtility object:_imageURL isEqualToObject:content.imageURL] &&
|
||||
[FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] &&
|
||||
[FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] &&
|
||||
[FBSDKInternalUtility object:_ref isEqualToObject:content.ref]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_contentDescription = [decoder decodeObjectOfClass:[NSString class]
|
||||
forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_DESCRIPTION_KEY];
|
||||
_contentTitle = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_TITLE_KEY];
|
||||
_contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_URL_KEY];
|
||||
_feedParameters = [decoder decodeObjectOfClass:[NSDictionary class] forKey:FBSDK_SHARE_STATUS_CONTENT_FEED_PARAMETERS_KEY];
|
||||
_imageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_STATUS_CONTENT_IMAGE_URL_KEY];
|
||||
_peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_STATUS_CONTENT_PEOPLE_IDS_KEY];
|
||||
_placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_PLACE_ID_KEY];
|
||||
_ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_REF_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_contentDescription forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_DESCRIPTION_KEY];
|
||||
[encoder encodeObject:_contentTitle forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_TITLE_KEY];
|
||||
[encoder encodeObject:_contentURL forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_URL_KEY];
|
||||
[encoder encodeObject:_feedParameters forKey:FBSDK_SHARE_STATUS_CONTENT_FEED_PARAMETERS_KEY];
|
||||
[encoder encodeObject:_imageURL forKey:FBSDK_SHARE_STATUS_CONTENT_IMAGE_URL_KEY];
|
||||
[encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_STATUS_CONTENT_PEOPLE_IDS_KEY];
|
||||
[encoder encodeObject:_placeID forKey:FBSDK_SHARE_STATUS_CONTENT_PLACE_ID_KEY];
|
||||
[encoder encodeObject:_ref forKey:FBSDK_SHARE_STATUS_CONTENT_REF_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKShareLinkContent *copy = [[FBSDKShareLinkContent alloc] init];
|
||||
copy->_contentDescription = [_contentDescription copy];
|
||||
copy->_contentTitle = [_contentTitle copy];
|
||||
copy->_contentURL = [_contentURL copy];
|
||||
copy->_feedParameters = [_feedParameters copy];
|
||||
copy->_imageURL = [_imageURL copy];
|
||||
copy->_peopleIDs = [_peopleIDs copy];
|
||||
copy->_placeID = [_placeID copy];
|
||||
copy->_ref = [_ref copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphObject.h>
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphValueContainer.h>
|
||||
|
||||
/*!
|
||||
@abstract An Open Graph Action for sharing.
|
||||
@discussion The property keys MUST have namespaces specified on them, such as `og:image`.
|
||||
*/
|
||||
@interface FBSDKShareOpenGraphAction : FBSDKShareOpenGraphValueContainer <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build a new action and set the object for the specified key.
|
||||
@param actionType The action type of the receiver
|
||||
@param object The Open Graph object represented by this action
|
||||
@param key The key for the object
|
||||
*/
|
||||
+ (instancetype)actionWithType:(NSString *)actionType object:(FBSDKShareOpenGraphObject *)object key:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build a new action and set the object for the specified key.
|
||||
@param actionType The action type of the receiver
|
||||
@param objectID The ID of an existing Open Graph object
|
||||
@param key The key for the object
|
||||
*/
|
||||
+ (instancetype)actionWithType:(NSString *)actionType objectID:(NSString *)objectID key:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build a new action and set the object for the specified key.
|
||||
@param actionType The action type of the receiver
|
||||
@param objectURL The URL to a page that defines the Open Graph object with meta tags
|
||||
@param key The key for the object
|
||||
*/
|
||||
+ (instancetype)actionWithType:(NSString *)actionType objectURL:(NSURL *)objectURL key:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Gets the action type.
|
||||
@return The action type
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *actionType;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another Open Graph Action.
|
||||
@param action The other action
|
||||
@return YES if the receiver's values are equal to the other action's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToShareOpenGraphAction:(FBSDKShareOpenGraphAction *)action;
|
||||
|
||||
@end
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareOpenGraphAction.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareOpenGraphValueContainer+Internal.h"
|
||||
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_ACTION_TYPE_KEY @"type"
|
||||
|
||||
@implementation FBSDKShareOpenGraphAction
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (instancetype)actionWithType:(NSString *)actionType object:(FBSDKShareOpenGraphObject *)object key:(NSString *)key
|
||||
{
|
||||
FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init];
|
||||
action.actionType = actionType;
|
||||
[action setObject:object forKey:key];
|
||||
return action;
|
||||
}
|
||||
|
||||
+ (instancetype)actionWithType:(NSString *)actionType objectID:(NSString *)objectID key:(NSString *)key
|
||||
{
|
||||
FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init];
|
||||
action.actionType = actionType;
|
||||
[action setString:objectID forKey:key];
|
||||
return action;
|
||||
}
|
||||
|
||||
+ (instancetype)actionWithType:(NSString *)actionType objectURL:(NSURL *)objectURL key:(NSString *)key
|
||||
{
|
||||
FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init];
|
||||
action.actionType = actionType;
|
||||
[action setURL:objectURL forKey:key];
|
||||
return action;
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return [FBSDKMath hashWithInteger:[super hash] andInteger:[_actionType hash]];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKShareOpenGraphAction class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToShareOpenGraphAction:(FBSDKShareOpenGraphAction *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToShareOpenGraphAction:(FBSDKShareOpenGraphAction *)action
|
||||
{
|
||||
return (action &&
|
||||
[FBSDKInternalUtility object:_actionType isEqualToObject:action.actionType] &&
|
||||
[self isEqualToShareOpenGraphValueContainer:action]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [super initWithCoder:decoder])) {
|
||||
_actionType = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_OPEN_GRAPH_ACTION_TYPE_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[super encodeWithCoder:encoder];
|
||||
[encoder encodeObject:_actionType forKey:FBSDK_SHARE_OPEN_GRAPH_ACTION_TYPE_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKShareOpenGraphAction *copy = [[FBSDKShareOpenGraphAction alloc] init];
|
||||
copy->_actionType = [_actionType copy];
|
||||
[copy parseProperties:[self allProperties]];
|
||||
return copy;
|
||||
}
|
||||
|
||||
#pragma mark - Internal Methods
|
||||
|
||||
- (BOOL)requireKeyNamespace
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphAction.h>
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
/*!
|
||||
@abstract A model for Open Graph content to be shared.
|
||||
*/
|
||||
@interface FBSDKShareOpenGraphContent : NSObject <FBSDKSharingContent>
|
||||
|
||||
/*!
|
||||
@abstract Open Graph Action to be shared.
|
||||
@return The action
|
||||
*/
|
||||
@property (nonatomic, copy) FBSDKShareOpenGraphAction *action;
|
||||
|
||||
/*!
|
||||
@abstract Property name that points to the primary Open Graph Object in the action.
|
||||
@discussion The value that this action points to will be use for rendering the preview for the share.
|
||||
@return The property name for the Open Graph Object in the action
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *previewPropertyName;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another Open Graph content.
|
||||
@param content The other content
|
||||
@return YES if the receiver's values are equal to the other content's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToShareOpenGraphContent:(FBSDKShareOpenGraphContent *)content;
|
||||
|
||||
@end
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareOpenGraphContent.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKSharePhoto.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_CONTENT_ACTION_KEY @"action"
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_CONTENT_CONTENT_URL_KEY @"contentURL"
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_CONTENT_PEOPLE_IDS_KEY @"peopleIDs"
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_CONTENT_PLACE_ID_KEY @"placeID"
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_CONTENT_PREVIEW_PROPERTY_NAME_KEY @"previewPropertyName"
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_CONTENT_REF_KEY @"ref"
|
||||
|
||||
@implementation FBSDKShareOpenGraphContent
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@synthesize contentURL = _contentURL;
|
||||
@synthesize peopleIDs = _peopleIDs;
|
||||
@synthesize placeID = _placeID;
|
||||
@synthesize ref = _ref;
|
||||
|
||||
- (void)setPeopleIDs:(NSArray *)peopleIDs
|
||||
{
|
||||
[FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"];
|
||||
if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) {
|
||||
_peopleIDs = [peopleIDs copy];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[_action hash],
|
||||
[_contentURL hash],
|
||||
[_peopleIDs hash],
|
||||
[_placeID hash],
|
||||
[_previewPropertyName hash],
|
||||
[_ref hash],
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToShareOpenGraphContent:(FBSDKShareOpenGraphContent *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToShareOpenGraphContent:(FBSDKShareOpenGraphContent *)content
|
||||
{
|
||||
return (content &&
|
||||
[FBSDKInternalUtility object:_action isEqualToObject:content.action] &&
|
||||
[FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] &&
|
||||
[FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] &&
|
||||
[FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] &&
|
||||
[FBSDKInternalUtility object:_previewPropertyName isEqualToObject:content.previewPropertyName] &&
|
||||
[FBSDKInternalUtility object:_ref isEqualToObject:content.ref]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_action = [decoder decodeObjectOfClass:[FBSDKShareOpenGraphAction class]
|
||||
forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_ACTION_KEY];
|
||||
_contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_CONTENT_URL_KEY];
|
||||
_peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PEOPLE_IDS_KEY];
|
||||
_placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PLACE_ID_KEY];
|
||||
_previewPropertyName = [decoder decodeObjectOfClass:[NSString class]
|
||||
forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PREVIEW_PROPERTY_NAME_KEY];
|
||||
_ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_REF_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_action forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_ACTION_KEY];
|
||||
[encoder encodeObject:_contentURL forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_CONTENT_URL_KEY];
|
||||
[encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PEOPLE_IDS_KEY];
|
||||
[encoder encodeObject:_placeID forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PLACE_ID_KEY];
|
||||
[encoder encodeObject:_previewPropertyName forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PREVIEW_PROPERTY_NAME_KEY];
|
||||
[encoder encodeObject:_ref forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_REF_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKShareOpenGraphContent *copy = [[FBSDKShareOpenGraphContent alloc] init];
|
||||
copy->_action = [_action copy];
|
||||
copy->_contentURL = [_contentURL copy];
|
||||
copy->_peopleIDs = [_peopleIDs copy];
|
||||
copy->_placeID = [_placeID copy];
|
||||
copy->_previewPropertyName = [_previewPropertyName copy];
|
||||
copy->_ref = [_ref copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphValueContainer.h>
|
||||
|
||||
/*!
|
||||
@abstract An Open Graph Object for sharing.
|
||||
@discussion The property keys MUST have namespaces specified on them, such as `og:image`,
|
||||
and `og:type` is required.
|
||||
|
||||
See https://developers.facebook.com/docs/sharing/opengraph/object-properties for other properties.
|
||||
|
||||
You can specify nested namespaces inline to define complex properties. For example, the following
|
||||
code will generate a fitness.course object with a location:
|
||||
|
||||
FBSDKShareOpenGraphObject *course = [FBSDKShareOpenGraphObject objectWithProperties:
|
||||
@{
|
||||
@"og:type": @"fitness.course",
|
||||
@"og:title": @"Sample course",
|
||||
@"fitness:metrics:location:latitude": @"41.40338",
|
||||
@"fitness:metrics:location:longitude": @"2.17403",
|
||||
}];
|
||||
*/
|
||||
@interface FBSDKShareOpenGraphObject : FBSDKShareOpenGraphValueContainer <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build a new action and set the object for the specified key.
|
||||
@param properties Properties for the Open Graph object, which will be parsed into the proper models
|
||||
*/
|
||||
+ (instancetype)objectWithProperties:(NSDictionary *)properties;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another Open Graph Object.
|
||||
@param object The other object
|
||||
@return YES if the receiver's values are equal to the other object's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToShareOpenGraphObject:(FBSDKShareOpenGraphObject *)object;
|
||||
|
||||
@end
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareOpenGraphObject.h"
|
||||
|
||||
#import "FBSDKShareOpenGraphValueContainer+Internal.h"
|
||||
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_OBJECT_DATA_KEY @"data"
|
||||
|
||||
@implementation FBSDKShareOpenGraphObject
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (instancetype)objectWithProperties:(NSDictionary *)properties
|
||||
{
|
||||
FBSDKShareOpenGraphObject *object = [[FBSDKShareOpenGraphObject alloc] init];
|
||||
[object parseProperties:properties];
|
||||
return object;
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKShareOpenGraphObject class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToShareOpenGraphObject:(FBSDKShareOpenGraphObject *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToShareOpenGraphObject:(FBSDKShareOpenGraphObject *)object
|
||||
{
|
||||
return [self isEqualToShareOpenGraphValueContainer:object];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKShareOpenGraphObject *copy = [[FBSDKShareOpenGraphObject alloc] init];
|
||||
[copy parseProperties:[self allProperties]];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+160
@@ -0,0 +1,160 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class FBSDKShareOpenGraphObject;
|
||||
@class FBSDKSharePhoto;
|
||||
|
||||
/*!
|
||||
@abstract Protocol defining operations on open graph actions and objects.
|
||||
@discussion The property keys MUST have namespaces specified on them, such as `og:image`.
|
||||
*/
|
||||
@protocol FBSDKShareOpenGraphValueContaining <NSObject, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract Gets an NSArray out of the receiver.
|
||||
@param key The key for the value
|
||||
@return The NSArray value or nil
|
||||
*/
|
||||
- (NSArray *)arrayForKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Applies a given block object to the entries of the receiver.
|
||||
@param block A block object to operate on entries in the receiver
|
||||
*/
|
||||
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(NSString *key, id object, BOOL *stop))block;
|
||||
|
||||
/*!
|
||||
@abstract Returns an enumerator object that lets you access each key in the receiver.
|
||||
@return An enumerator object that lets you access each key in the receiver
|
||||
*/
|
||||
- (NSEnumerator *)keyEnumerator;
|
||||
|
||||
/*!
|
||||
@abstract Gets an NSNumber out of the receiver.
|
||||
@param key The key for the value
|
||||
@return The NSNumber value or nil
|
||||
*/
|
||||
- (NSNumber *)numberForKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Returns an enumerator object that lets you access each value in the receiver.
|
||||
@return An enumerator object that lets you access each value in the receiver
|
||||
*/
|
||||
- (NSEnumerator *)objectEnumerator;
|
||||
|
||||
/*!
|
||||
@abstract Gets an FBSDKShareOpenGraphObject out of the receiver.
|
||||
@param key The key for the value
|
||||
@return The FBSDKShareOpenGraphObject value or nil
|
||||
*/
|
||||
- (FBSDKShareOpenGraphObject *)objectForKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Enables subscript access to the values in the receiver.
|
||||
@param key The key for the value
|
||||
@return The value
|
||||
*/
|
||||
- (id)objectForKeyedSubscript:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Parses properties out of a dictionary into the receiver.
|
||||
@param properties The properties to parse.
|
||||
*/
|
||||
- (void)parseProperties:(NSDictionary *)properties;
|
||||
|
||||
/*!
|
||||
@abstract Gets an FBSDKSharePhoto out of the receiver.
|
||||
@param key The key for the value
|
||||
@return The FBSDKSharePhoto value or nil
|
||||
*/
|
||||
- (FBSDKSharePhoto *)photoForKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Removes a value from the receiver for the specified key.
|
||||
@param key The key for the value
|
||||
*/
|
||||
- (void)removeObjectForKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Sets an NSArray on the receiver.
|
||||
@discussion This method will throw if the array contains any values that is not an NSNumber, NSString, NSURL,
|
||||
FBSDKSharePhoto or FBSDKShareOpenGraphObject.
|
||||
@param array The NSArray value
|
||||
@param key The key for the value
|
||||
*/
|
||||
- (void)setArray:(NSArray *)array forKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Sets an NSNumber on the receiver.
|
||||
@param number The NSNumber value
|
||||
@param key The key for the value
|
||||
*/
|
||||
- (void)setNumber:(NSNumber *)number forKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Sets an FBSDKShareOpenGraphObject on the receiver.
|
||||
@param object The FBSDKShareOpenGraphObject value
|
||||
@param key The key for the value
|
||||
*/
|
||||
- (void)setObject:(FBSDKShareOpenGraphObject *)object forKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Sets an FBSDKSharePhoto on the receiver.
|
||||
@param photo The FBSDKSharePhoto value
|
||||
@param key The key for the value
|
||||
*/
|
||||
- (void)setPhoto:(FBSDKSharePhoto *)photo forKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Sets an NSString on the receiver.
|
||||
@param string The NSString value
|
||||
@param key The key for the value
|
||||
*/
|
||||
- (void)setString:(NSString *)string forKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Sets an NSURL on the receiver.
|
||||
@param URL The NSURL value
|
||||
@param key The key for the value
|
||||
*/
|
||||
- (void)setURL:(NSURL *)URL forKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Gets an NSString out of the receiver.
|
||||
@param key The key for the value
|
||||
@return The NSString value or nil
|
||||
*/
|
||||
- (NSString *)stringForKey:(NSString *)key;
|
||||
|
||||
/*!
|
||||
@abstract Gets an NSURL out of the receiver.
|
||||
@param key The key for the value
|
||||
@return The NSURL value or nil
|
||||
*/
|
||||
- (NSURL *)URLForKey:(NSString *)key;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract A base class to container Open Graph values.
|
||||
*/
|
||||
@interface FBSDKShareOpenGraphValueContainer : NSObject <FBSDKShareOpenGraphValueContaining>
|
||||
|
||||
@end
|
||||
Generated
+238
@@ -0,0 +1,238 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareOpenGraphValueContainer.h"
|
||||
#import "FBSDKShareOpenGraphValueContainer+Internal.h"
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareOpenGraphObject.h"
|
||||
#import "FBSDKSharePhoto.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_VALUE_CONTAINER_PROPERTIES_KEY @"properties"
|
||||
|
||||
@implementation FBSDKShareOpenGraphValueContainer
|
||||
{
|
||||
NSMutableDictionary *_properties;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_properties = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (NSDictionary *)allData
|
||||
{
|
||||
return [_properties copy];
|
||||
}
|
||||
|
||||
- (NSArray *)arrayForKey:(NSString *)key
|
||||
{
|
||||
return [self _valueOfClass:[NSArray class] forKey:key];
|
||||
}
|
||||
|
||||
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(NSString *key, id object, BOOL *stop))block
|
||||
{
|
||||
[_properties enumerateKeysAndObjectsUsingBlock:block];
|
||||
}
|
||||
|
||||
- (NSEnumerator *)keyEnumerator
|
||||
{
|
||||
return [_properties keyEnumerator];
|
||||
}
|
||||
|
||||
- (NSNumber *)numberForKey:(NSString *)key
|
||||
{
|
||||
return [self _valueOfClass:[NSNumber class] forKey:key];
|
||||
}
|
||||
|
||||
- (NSEnumerator *)objectEnumerator
|
||||
{
|
||||
return [_properties objectEnumerator];
|
||||
}
|
||||
|
||||
- (FBSDKShareOpenGraphObject *)objectForKey:(NSString *)key
|
||||
{
|
||||
return [self _valueOfClass:[FBSDKShareOpenGraphObject class] forKey:key];
|
||||
}
|
||||
|
||||
- (id)objectForKeyedSubscript:(id<NSCopying>)key
|
||||
{
|
||||
return [self _valueForKey:key];
|
||||
}
|
||||
|
||||
- (void)parseProperties:(NSDictionary *)properties
|
||||
{
|
||||
[FBSDKShareUtility assertOpenGraphValues:properties requireKeyNamespace:[self requireKeyNamespace]];
|
||||
[_properties addEntriesFromDictionary:[FBSDKShareUtility convertOpenGraphValues:properties]];
|
||||
}
|
||||
|
||||
- (FBSDKSharePhoto *)photoForKey:(NSString *)key
|
||||
{
|
||||
return [self _valueOfClass:[FBSDKSharePhoto class] forKey:key];
|
||||
}
|
||||
|
||||
- (void)removeObjectForKey:(NSString *)key
|
||||
{
|
||||
[_properties removeObjectForKey:key];
|
||||
}
|
||||
|
||||
- (void)setArray:(NSArray *)array forKey:(NSString *)key
|
||||
{
|
||||
[self _setValue:array forKey:key];
|
||||
}
|
||||
|
||||
- (void)setNumber:(NSNumber *)number forKey:(NSString *)key
|
||||
{
|
||||
[self _setValue:number forKey:key];
|
||||
}
|
||||
|
||||
- (void)setObject:(FBSDKShareOpenGraphObject *)object forKey:(NSString *)key
|
||||
{
|
||||
[self _setValue:object forKey:key];
|
||||
}
|
||||
|
||||
- (void)setPhoto:(FBSDKSharePhoto *)photo forKey:(NSString *)key
|
||||
{
|
||||
[self _setValue:photo forKey:key];
|
||||
}
|
||||
|
||||
- (void)setString:(NSString *)string forKey:(NSString *)key
|
||||
{
|
||||
[self _setValue:string forKey:key];
|
||||
}
|
||||
|
||||
- (void)setURL:(NSURL *)URL forKey:(NSString *)key
|
||||
{
|
||||
[self _setValue:URL forKey:key];
|
||||
}
|
||||
- (NSString *)stringForKey:(NSString *)key
|
||||
{
|
||||
return [self _valueOfClass:[NSString class] forKey:key];
|
||||
}
|
||||
|
||||
- (NSURL *)URLForKey:(NSString *)key
|
||||
{
|
||||
return [self _valueOfClass:[NSURL class] forKey:key];
|
||||
}
|
||||
|
||||
- (id)valueForKey:(NSString *)key
|
||||
{
|
||||
return [self _valueForKey:key] ?: [super valueForKey:key];
|
||||
}
|
||||
|
||||
#pragma mark - Internal Methods
|
||||
|
||||
- (NSDictionary *)allProperties
|
||||
{
|
||||
return _properties;
|
||||
}
|
||||
|
||||
- (BOOL)requireKeyNamespace
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return [_properties hash];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKShareOpenGraphValueContainer class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToShareOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToShareOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object
|
||||
{
|
||||
return [FBSDKInternalUtility object:_properties isEqualToObject:[object allProperties]];
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
NSSet *classes = [NSSet setWithObjects:
|
||||
[NSArray class],
|
||||
[NSDictionary class],
|
||||
[FBSDKShareOpenGraphObject class],
|
||||
[FBSDKSharePhoto class],
|
||||
nil];
|
||||
NSDictionary *properties = [decoder decodeObjectOfClasses:classes
|
||||
forKey:FBSDK_SHARE_OPEN_GRAPH_VALUE_CONTAINER_PROPERTIES_KEY];
|
||||
if ([properties count]) {
|
||||
[self parseProperties:properties];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_properties forKey:FBSDK_SHARE_OPEN_GRAPH_VALUE_CONTAINER_PROPERTIES_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_setValue:(id)value forKey:(NSString *)key
|
||||
{
|
||||
[FBSDKShareUtility assertOpenGraphKey:key requireNamespace:[self requireKeyNamespace]];
|
||||
[FBSDKShareUtility assertOpenGraphValue:value];
|
||||
if (value) {
|
||||
_properties[key] = value;
|
||||
} else {
|
||||
[self removeObjectForKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)_valueForKey:(id)key
|
||||
{
|
||||
key = [FBSDKTypeUtility stringValue:key];
|
||||
return (key ? [FBSDKTypeUtility objectValue:_properties[key]] : nil);
|
||||
}
|
||||
|
||||
- (id)_valueOfClass:(__unsafe_unretained Class)cls forKey:(NSString *)key
|
||||
{
|
||||
id value = [self _valueForKey:key];
|
||||
return ([value isKindOfClass:cls] ? value : nil);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
/*!
|
||||
@abstract A photo for sharing.
|
||||
*/
|
||||
@interface FBSDKSharePhoto : NSObject <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build a new photo object with an image.
|
||||
@param image If the photo is resident in memory, this method supplies the data
|
||||
@param userGenerated Specifies whether the photo represented by the receiver was generated by the user or by the
|
||||
application
|
||||
*/
|
||||
+ (instancetype)photoWithImage:(UIImage *)image userGenerated:(BOOL)userGenerated;
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build a new photo object with an imageURL.
|
||||
@param imageURL The URL to the photo
|
||||
@param userGenerated Specifies whether the photo represented by the receiver was generated by the user or by the
|
||||
application
|
||||
@discussion This method should only be used when adding photo content to open graph stories.
|
||||
For example, if you're trying to share a photo from the web by itself, download the image and use
|
||||
`photoWithImage:userGenerated:` instead.
|
||||
*/
|
||||
+ (instancetype)photoWithImageURL:(NSURL *)imageURL userGenerated:(BOOL)userGenerated;
|
||||
|
||||
/*!
|
||||
@abstract If the photo is resident in memory, this method supplies the data.
|
||||
@return UIImage representation of the photo
|
||||
*/
|
||||
@property (nonatomic, strong) UIImage *image;
|
||||
|
||||
/*!
|
||||
@abstract The URL to the photo.
|
||||
@return URL that points to a network location or the location of the photo on disk
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL *imageURL;
|
||||
|
||||
/*!
|
||||
@abstract Specifies whether the photo represented by the receiver was generated by the user or by the application.
|
||||
@return YES if the photo is user-generated, otherwise NO
|
||||
*/
|
||||
@property (nonatomic, assign, getter=isUserGenerated) BOOL userGenerated;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another photo.
|
||||
@param photo The other photo
|
||||
@return YES if the receiver's values are equal to the other photo's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToSharePhoto:(FBSDKSharePhoto *)photo;
|
||||
|
||||
/*!
|
||||
@abstract The user generated caption for the photo. Note that the 'caption' must come from
|
||||
* the user, as pre-filled content is forbidden by the Platform Policies (2.3).
|
||||
@return the Photo's caption if exists else returns null.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *caption;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKSharePhoto.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
#define FBSDK_SHARE_PHOTO_IMAGE_KEY @"image"
|
||||
#define FBSDK_SHARE_PHOTO_IMAGE_URL_KEY @"imageURL"
|
||||
#define FBSDK_SHARE_PHOTO_USER_GENERATED_KEY @"userGenerated"
|
||||
#define FBSDK_SHARE_PHOTO_CAPTION_KEY @"caption"
|
||||
|
||||
@implementation FBSDKSharePhoto
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (instancetype)photoWithImage:(UIImage *)image userGenerated:(BOOL)userGenerated
|
||||
{
|
||||
FBSDKSharePhoto *photo = [[self alloc] init];
|
||||
photo.image = image;
|
||||
photo.userGenerated = userGenerated;
|
||||
return photo;
|
||||
}
|
||||
|
||||
+ (instancetype)photoWithImageURL:(NSURL *)imageURL userGenerated:(BOOL)userGenerated
|
||||
{
|
||||
FBSDKSharePhoto *photo = [[self alloc] init];
|
||||
photo.imageURL = imageURL;
|
||||
photo.userGenerated = userGenerated;
|
||||
return photo;
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[_image hash],
|
||||
[_imageURL hash],
|
||||
[_caption hash],
|
||||
(_userGenerated ? 1u : 0u)
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKSharePhoto class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToSharePhoto:(FBSDKSharePhoto *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToSharePhoto:(FBSDKSharePhoto *)photo
|
||||
{
|
||||
return (photo &&
|
||||
(_userGenerated == photo.userGenerated) &&
|
||||
[FBSDKInternalUtility object:_image isEqualToObject:photo.image] &&
|
||||
[FBSDKInternalUtility object:_imageURL isEqualToObject:photo.imageURL] &&
|
||||
[FBSDKInternalUtility object:_caption isEqualToObject:photo.caption]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_image = [decoder decodeObjectOfClass:[UIImage class] forKey:FBSDK_SHARE_PHOTO_IMAGE_KEY];
|
||||
_imageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_PHOTO_IMAGE_URL_KEY];
|
||||
_userGenerated = [decoder decodeBoolForKey:FBSDK_SHARE_PHOTO_USER_GENERATED_KEY];
|
||||
_caption = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_PHOTO_CAPTION_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_image forKey:FBSDK_SHARE_PHOTO_IMAGE_KEY];
|
||||
[encoder encodeObject:_imageURL forKey:FBSDK_SHARE_PHOTO_IMAGE_URL_KEY];
|
||||
[encoder encodeBool:_userGenerated forKey:FBSDK_SHARE_PHOTO_USER_GENERATED_KEY];
|
||||
[encoder encodeObject:_caption forKey:FBSDK_SHARE_PHOTO_CAPTION_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKSharePhoto *copy = [[FBSDKSharePhoto alloc] init];
|
||||
copy->_image = [_image copy];
|
||||
copy->_imageURL = [_imageURL copy];
|
||||
copy->_userGenerated = _userGenerated;
|
||||
copy->_caption = [_caption copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
/*!
|
||||
@abstract A model for photo content to be shared.
|
||||
*/
|
||||
@interface FBSDKSharePhotoContent : NSObject <FBSDKSharingContent>
|
||||
|
||||
/*!
|
||||
@abstract Photos to be shared.
|
||||
@return Array of the photos (FBSDKSharePhoto)
|
||||
*/
|
||||
@property (nonatomic, copy) NSArray *photos;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another photo content.
|
||||
@param content The other content
|
||||
@return YES if the receiver's values are equal to the other content's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToSharePhotoContent:(FBSDKSharePhotoContent *)content;
|
||||
|
||||
@end
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKSharePhotoContent.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKSharePhoto.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#define FBSDK_SHARE_PHOTO_CONTENT_CONTENT_URL_KEY @"contentURL"
|
||||
#define FBSDK_SHARE_PHOTO_CONTENT_PEOPLE_IDS_KEY @"peopleIDs"
|
||||
#define FBSDK_SHARE_PHOTO_CONTENT_PHOTOS_KEY @"photos"
|
||||
#define FBSDK_SHARE_PHOTO_CONTENT_PLACE_ID_KEY @"placeID"
|
||||
#define FBSDK_SHARE_PHOTO_CONTENT_REF_KEY @"ref"
|
||||
|
||||
@implementation FBSDKSharePhotoContent
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@synthesize contentURL = _contentURL;
|
||||
@synthesize peopleIDs = _peopleIDs;
|
||||
@synthesize placeID = _placeID;
|
||||
@synthesize ref = _ref;
|
||||
|
||||
- (void)setPeopleIDs:(NSArray *)peopleIDs
|
||||
{
|
||||
[FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"];
|
||||
if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) {
|
||||
_peopleIDs = [peopleIDs copy];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setPhotos:(NSArray *)photos
|
||||
{
|
||||
[FBSDKShareUtility assertCollection:photos ofClass:[FBSDKSharePhoto class] name:@"photos"];
|
||||
if (![FBSDKInternalUtility object:_photos isEqualToObject:photos]) {
|
||||
_photos = [photos copy];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[_contentURL hash],
|
||||
[_peopleIDs hash],
|
||||
[_photos hash],
|
||||
[_placeID hash],
|
||||
[_ref hash],
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToSharePhotoContent:(FBSDKSharePhotoContent *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToSharePhotoContent:(FBSDKSharePhotoContent *)content
|
||||
{
|
||||
return (content &&
|
||||
[FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] &&
|
||||
[FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] &&
|
||||
[FBSDKInternalUtility object:_photos isEqualToObject:content.photos] &&
|
||||
[FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] &&
|
||||
[FBSDKInternalUtility object:_ref isEqualToObject:content.ref]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_PHOTO_CONTENT_CONTENT_URL_KEY];
|
||||
_peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_PHOTO_CONTENT_PEOPLE_IDS_KEY];
|
||||
NSSet *classes = [NSSet setWithObjects:[NSArray class], [FBSDKSharePhoto class], nil];
|
||||
_photos = [decoder decodeObjectOfClasses:classes forKey:FBSDK_SHARE_PHOTO_CONTENT_PHOTOS_KEY];
|
||||
_placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_PHOTO_CONTENT_PLACE_ID_KEY];
|
||||
_ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_PHOTO_CONTENT_REF_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_contentURL forKey:FBSDK_SHARE_PHOTO_CONTENT_CONTENT_URL_KEY];
|
||||
[encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_PHOTO_CONTENT_PEOPLE_IDS_KEY];
|
||||
[encoder encodeObject:_photos forKey:FBSDK_SHARE_PHOTO_CONTENT_PHOTOS_KEY];
|
||||
[encoder encodeObject:_placeID forKey:FBSDK_SHARE_PHOTO_CONTENT_PLACE_ID_KEY];
|
||||
[encoder encodeObject:_ref forKey:FBSDK_SHARE_PHOTO_CONTENT_REF_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKSharePhotoContent *copy = [[FBSDKSharePhotoContent alloc] init];
|
||||
copy->_contentURL = [_contentURL copy];
|
||||
copy->_peopleIDs = [_peopleIDs copy];
|
||||
copy->_photos = [_photos copy];
|
||||
copy->_placeID = [_placeID copy];
|
||||
copy->_ref = [_ref copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
/*!
|
||||
@abstract A video for sharing.
|
||||
*/
|
||||
@interface FBSDKShareVideo : NSObject <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract Convenience method to build a new video object with a videoURL.
|
||||
@param videoURL The URL to the video
|
||||
application
|
||||
*/
|
||||
+ (instancetype)videoWithVideoURL:(NSURL *)videoURL;
|
||||
|
||||
/*!
|
||||
@abstract The file URL to the video.
|
||||
@return URL that points to the location of the video on disk
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL *videoURL;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another video.
|
||||
@param video The other video
|
||||
@return YES if the receiver's values are equal to the other video's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToShareVideo:(FBSDKShareVideo *)video;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareVideo.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
#define FBSDK_SHARE_VIDEO_URL_KEY @"videoURL"
|
||||
|
||||
@implementation FBSDKShareVideo
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (instancetype)videoWithVideoURL:(NSURL *)videoURL
|
||||
{
|
||||
FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init];
|
||||
video.videoURL = videoURL;
|
||||
return video;
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return [_videoURL hash];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKShareVideo class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToShareVideo:(FBSDKShareVideo *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToShareVideo:(FBSDKShareVideo *)video
|
||||
{
|
||||
return (video &&
|
||||
[FBSDKInternalUtility object:_videoURL isEqualToObject:video.videoURL]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_videoURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_VIDEO_URL_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_videoURL forKey:FBSDK_SHARE_VIDEO_URL_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKShareVideo *copy = [[FBSDKShareVideo alloc] init];
|
||||
copy->_videoURL = [_videoURL copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharePhoto.h>
|
||||
#import <FBSDKShareKit/FBSDKShareVideo.h>
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
/*!
|
||||
@abstract A model for video content to be shared.
|
||||
*/
|
||||
@interface FBSDKShareVideoContent : NSObject <FBSDKSharingContent>
|
||||
|
||||
/*!
|
||||
@abstract The photo that represents the video.
|
||||
@return The photo
|
||||
*/
|
||||
@property (nonatomic, copy) FBSDKSharePhoto *previewPhoto;
|
||||
|
||||
/*!
|
||||
@abstract The video to be shared.
|
||||
@return The video
|
||||
*/
|
||||
@property (nonatomic, copy) FBSDKShareVideo *video;
|
||||
|
||||
/*!
|
||||
@abstract Compares the receiver to another video content.
|
||||
@param content The other content
|
||||
@return YES if the receiver's values are equal to the other content's values; otherwise NO
|
||||
*/
|
||||
- (BOOL)isEqualToShareVideoContent:(FBSDKShareVideoContent *)content;
|
||||
|
||||
@end
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareVideoContent.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#define FBSDK_SHARE_VIDEO_CONTENT_CONTENT_URL_KEY @"contentURL"
|
||||
#define FBSDK_SHARE_VIDEO_CONTENT_PEOPLE_IDS_KEY @"peopleIDs"
|
||||
#define FBSDK_SHARE_VIDEO_CONTENT_PLACE_ID_KEY @"placeID"
|
||||
#define FBSDK_SHARE_VIDEO_CONTENT_PREVIEW_PHOTO_KEY @"previewPhoto"
|
||||
#define FBSDK_SHARE_VIDEO_CONTENT_REF_KEY @"ref"
|
||||
#define FBSDK_SHARE_VIDEO_CONTENT_VIDEO_KEY @"video"
|
||||
|
||||
@implementation FBSDKShareVideoContent
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@synthesize contentURL = _contentURL;
|
||||
@synthesize peopleIDs = _peopleIDs;
|
||||
@synthesize placeID = _placeID;
|
||||
@synthesize ref = _ref;
|
||||
|
||||
- (void)setPeopleIDs:(NSArray *)peopleIDs
|
||||
{
|
||||
[FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"];
|
||||
if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) {
|
||||
_peopleIDs = [peopleIDs copy];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Equality
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger subhashes[] = {
|
||||
[_contentURL hash],
|
||||
[_peopleIDs hash],
|
||||
[_placeID hash],
|
||||
[_previewPhoto hash],
|
||||
[_ref hash],
|
||||
[_video hash],
|
||||
};
|
||||
return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
if (![object isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
return NO;
|
||||
}
|
||||
return [self isEqualToShareVideoContent:(FBSDKShareVideoContent *)object];
|
||||
}
|
||||
|
||||
- (BOOL)isEqualToShareVideoContent:(FBSDKShareVideoContent *)content
|
||||
{
|
||||
return (content &&
|
||||
[FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] &&
|
||||
[FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] &&
|
||||
[FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] &&
|
||||
[FBSDKInternalUtility object:_previewPhoto isEqualToObject:content.previewPhoto] &&
|
||||
[FBSDKInternalUtility object:_ref isEqualToObject:content.ref] &&
|
||||
[FBSDKInternalUtility object:_video isEqualToObject:content.video]);
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [self init])) {
|
||||
_contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_VIDEO_CONTENT_CONTENT_URL_KEY];
|
||||
_peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_VIDEO_CONTENT_PEOPLE_IDS_KEY];
|
||||
_placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_VIDEO_CONTENT_PLACE_ID_KEY];
|
||||
_previewPhoto = [decoder decodeObjectOfClass:[FBSDKSharePhoto class]
|
||||
forKey:FBSDK_SHARE_VIDEO_CONTENT_PREVIEW_PHOTO_KEY];
|
||||
_ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_VIDEO_CONTENT_REF_KEY];
|
||||
_video = [decoder decodeObjectOfClass:[FBSDKShareVideo class] forKey:FBSDK_SHARE_VIDEO_CONTENT_VIDEO_KEY];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_contentURL forKey:FBSDK_SHARE_VIDEO_CONTENT_CONTENT_URL_KEY];
|
||||
[encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_VIDEO_CONTENT_PEOPLE_IDS_KEY];
|
||||
[encoder encodeObject:_placeID forKey:FBSDK_SHARE_VIDEO_CONTENT_PLACE_ID_KEY];
|
||||
[encoder encodeObject:_previewPhoto forKey:FBSDK_SHARE_VIDEO_CONTENT_PREVIEW_PHOTO_KEY];
|
||||
[encoder encodeObject:_ref forKey:FBSDK_SHARE_VIDEO_CONTENT_REF_KEY];
|
||||
[encoder encodeObject:_video forKey:FBSDK_SHARE_VIDEO_CONTENT_VIDEO_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
FBSDKShareVideoContent *copy = [[FBSDKShareVideoContent alloc] init];
|
||||
copy->_contentURL = [_contentURL copy];
|
||||
copy->_peopleIDs = [_peopleIDs copy];
|
||||
copy->_placeID = [_placeID copy];
|
||||
copy->_previewPhoto = [_previewPhoto copy];
|
||||
copy->_ref = [_ref copy];
|
||||
copy->_video = [_video copy];
|
||||
return copy;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
@protocol FBSDKSharingDelegate;
|
||||
|
||||
/*!
|
||||
@abstract The common interface for components that initiate sharing.
|
||||
@see FBSDKShareDialog
|
||||
@see FBSDKMessageDialog
|
||||
@see FBSDKShareAPI
|
||||
*/
|
||||
@protocol FBSDKSharing <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract The receiver's delegate or nil if it doesn't have a delegate.
|
||||
*/
|
||||
@property (nonatomic, weak) id<FBSDKSharingDelegate> delegate;
|
||||
|
||||
/*!
|
||||
@abstract The content to be shared.
|
||||
*/
|
||||
@property (nonatomic, copy) id<FBSDKSharingContent> shareContent;
|
||||
|
||||
/*!
|
||||
@abstract A Boolean value that indicates whether the receiver should fail if it finds an error with the share content.
|
||||
@discussion If NO, the sharer will still be displayed without the data that was mis-configured. For example, an
|
||||
invalid placeID specified on the shareContent would produce a data error.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldFailOnDataError;
|
||||
|
||||
/*!
|
||||
@abstract Validates the content on the receiver.
|
||||
@param errorRef If an error occurs, upon return contains an NSError object that describes the problem.
|
||||
@return YES if the content is valid, otherwise NO.
|
||||
*/
|
||||
- (BOOL)validateWithError:(NSError **)errorRef;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract The common interface for dialogs that initiate sharing.
|
||||
*/
|
||||
@protocol FBSDKSharingDialog <FBSDKSharing>
|
||||
|
||||
/*!
|
||||
@abstract A Boolean value that indicates whether the receiver can initiate a share.
|
||||
@discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is
|
||||
required but not available. This method does not validate the content on the receiver, so this can be checked before
|
||||
building up the content.
|
||||
@see [FBSDKSharing validateWithError:]
|
||||
@result YES if the receiver can share, otherwise NO.
|
||||
*/
|
||||
- (BOOL)canShow;
|
||||
|
||||
/*!
|
||||
@abstract Shows the dialog.
|
||||
@result YES if the receiver was able to begin sharing, otherwise NO.
|
||||
*/
|
||||
- (BOOL)show;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract A delegate for FBSDKSharing.
|
||||
@discussion The delegate is notified with the results of the sharer as long as the application has permissions to
|
||||
receive the information. For example, if the person is not signed into the containing app, the sharer may not be able
|
||||
to distinguish between completion of a share and cancellation.
|
||||
*/
|
||||
@protocol FBSDKSharingDelegate <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the share completes without error or cancellation.
|
||||
@param sharer The FBSDKSharing that completed.
|
||||
@param results The results from the sharer. This may be nil or empty.
|
||||
*/
|
||||
- (void)sharer:(id<FBSDKSharing>)sharer didCompleteWithResults:(NSDictionary *)results;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the sharer encounters an error.
|
||||
@param sharer The FBSDKSharing that completed.
|
||||
@param error The error.
|
||||
*/
|
||||
- (void)sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error;
|
||||
|
||||
/*!
|
||||
@abstract Sent to the delegate when the sharer is cancelled.
|
||||
@param sharer The FBSDKSharing that completed.
|
||||
*/
|
||||
- (void)sharerDidCancel:(id<FBSDKSharing>)sharer;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
/*!
|
||||
@abstract The common interface for sharing buttons.
|
||||
@see FBSDKSendButton
|
||||
@see FBSDKShareButton
|
||||
*/
|
||||
@protocol FBSDKSharingButton <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract The content to be shared.
|
||||
*/
|
||||
@property (nonatomic, copy) id<FBSDKSharingContent> shareContent;
|
||||
|
||||
@end
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCopying.h>
|
||||
|
||||
/*!
|
||||
@abstract A base interface for content to be shared.
|
||||
*/
|
||||
@protocol FBSDKSharingContent <FBSDKCopying, NSSecureCoding>
|
||||
|
||||
/*!
|
||||
@abstract URL for the content being shared.
|
||||
@discussion This URL will be checked for all link meta tags for linking in platform specific ways. See documentation
|
||||
for App Links (https://developers.facebook.com/docs/applinks/)
|
||||
@return URL representation of the content link
|
||||
*/
|
||||
@property (nonatomic, copy) NSURL *contentURL;
|
||||
|
||||
/*!
|
||||
@abstract List of IDs for taggable people to tag with this content.
|
||||
@description See documentation for Taggable Friends
|
||||
(https://developers.facebook.com/docs/graph-api/reference/user/taggable_friends)
|
||||
@return Array of IDs for people to tag (NSString)
|
||||
*/
|
||||
@property (nonatomic, copy) NSArray *peopleIDs;
|
||||
|
||||
/*!
|
||||
@abstract The ID for a place to tag with this content.
|
||||
@return The ID for the place to tag
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *placeID;
|
||||
|
||||
/*!
|
||||
@abstract A value to be added to the referrer URL when a person follows a link from this shared content on feed.
|
||||
@return The ref for the content.
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *ref;
|
||||
|
||||
@end
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
@interface FBSDKCheckmarkIcon : FBSDKIcon
|
||||
|
||||
@end
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKCheckmarkIcon.h"
|
||||
|
||||
@implementation FBSDKCheckmarkIcon
|
||||
|
||||
- (CGPathRef)pathWithSize:(CGSize)size
|
||||
{
|
||||
CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / 100.0, size.height / 100.0);
|
||||
CGAffineTransform *transform = &transformValue;
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, transform, 0.0, 50.0);
|
||||
const CGPoint points[] = {
|
||||
CGPointMake(12.0, 38.0),
|
||||
CGPointMake(37.0, 63.0),
|
||||
CGPointMake(87.0, 13.0),
|
||||
CGPointMake(99.0, 25.0),
|
||||
CGPointMake(37.0, 87.0),
|
||||
CGPointMake(0.0, 48.0),
|
||||
};
|
||||
CGPathAddLines(path, transform, points, sizeof(points) / sizeof(points[0]));
|
||||
CGPathRef result = CGPathCreateCopy(path);
|
||||
CGPathRelease(path);
|
||||
return CFAutorelease(result);
|
||||
}
|
||||
|
||||
@end
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface FBSDKGameRequestFrictionlessRecipientCache : NSObject
|
||||
|
||||
- (BOOL)recipientsAreFrictionless:(id)recipients;
|
||||
- (void)updateWithResults:(NSDictionary *)results;
|
||||
|
||||
@end
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKGameRequestFrictionlessRecipientCache.h"
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
@implementation FBSDKGameRequestFrictionlessRecipientCache
|
||||
{
|
||||
NSSet *_recipientIDs;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(_accessTokenDidChangeNotification:)
|
||||
name:FBSDKAccessTokenDidChangeNotification
|
||||
object:nil];
|
||||
[self _updateCache];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
#pragma mark - Public API
|
||||
|
||||
- (BOOL)recipientsAreFrictionless:(id)recipients
|
||||
{
|
||||
if (!recipients) {
|
||||
return NO;
|
||||
}
|
||||
NSArray *recipientIDArray = [FBSDKTypeUtility arrayValue:recipients];
|
||||
if (!recipientIDArray && [recipients isKindOfClass:[NSString class]]) {
|
||||
recipientIDArray = [recipients componentsSeparatedByString:@","];
|
||||
}
|
||||
NSSet *recipientIDs = [[NSSet alloc] initWithArray:recipientIDArray];
|
||||
return [recipientIDs isSubsetOfSet:_recipientIDs];
|
||||
}
|
||||
|
||||
- (void)updateWithResults:(NSDictionary *)results
|
||||
{
|
||||
if ([FBSDKTypeUtility boolValue:results[@"updated_frictionless"]]) {
|
||||
[self _updateCache];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_accessTokenDidChangeNotification:(NSNotification *)notification
|
||||
{
|
||||
if (![notification.userInfo[FBSDKAccessTokenDidChangeUserID] boolValue]) {
|
||||
return;
|
||||
}
|
||||
_recipientIDs = nil;
|
||||
[self _updateCache];
|
||||
}
|
||||
|
||||
- (void)_updateCache
|
||||
{
|
||||
if (![FBSDKAccessToken currentAccessToken]) {
|
||||
_recipientIDs = nil;
|
||||
}
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/apprequestformerrecipients"
|
||||
parameters:@{@"fields":@""}
|
||||
flags:(FBSDKGraphRequestFlagDoNotInvalidateTokenOnError |
|
||||
FBSDKGraphRequestFlagDisableErrorRecovery)];
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (!error) {
|
||||
NSArray *items = [FBSDKTypeUtility arrayValue:result[@"data"]];
|
||||
NSArray *recipientIDs = [items valueForKey:@"recipient_id"];
|
||||
_recipientIDs = [[NSSet alloc] initWithArray:recipientIDs];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+48
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKMacros.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKLikeObjectType.h>
|
||||
|
||||
FBSDK_EXTERN NSString *const FBSDKLikeActionControllerDidDisableNotification;
|
||||
FBSDK_EXTERN NSString *const FBSDKLikeActionControllerDidResetNotification;
|
||||
FBSDK_EXTERN NSString *const FBSDKLikeActionControllerDidUpdateNotification;
|
||||
FBSDK_EXTERN NSString *const FBSDKLikeActionControllerAnimatedKey;
|
||||
|
||||
@interface FBSDKLikeActionController : NSObject <NSDiscardableContent, NSSecureCoding>
|
||||
|
||||
+ (BOOL)isDisabled;
|
||||
|
||||
// this method will call beginContentAccess before returning the instance
|
||||
+ (instancetype)likeActionControllerForObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType;
|
||||
|
||||
@property (nonatomic, copy, readonly) NSDate *lastUpdateTime;
|
||||
@property (nonatomic, copy, readonly) NSString *likeCountString;
|
||||
@property (nonatomic, copy, readonly) NSString *objectID;
|
||||
@property (nonatomic, assign, readonly) FBSDKLikeObjectType objectType;
|
||||
@property (nonatomic, assign, readonly) BOOL objectIsLiked;
|
||||
@property (nonatomic, copy, readonly) NSString *socialSentence;
|
||||
|
||||
- (void)refresh;
|
||||
- (void)toggleLikeWithSoundEnabled:(BOOL)soundEnabled analyticsParameters:(NSDictionary *)analyticsParameters fromViewController:(UIViewController *)fromViewController;
|
||||
|
||||
@end
|
||||
Generated
+1069
File diff suppressed because it is too large.
Load diff
Generated
+31
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface FBSDKLikeActionControllerCache : NSObject <NSSecureCoding>
|
||||
|
||||
- (instancetype)initWithAccessTokenString:(NSString *)accessTokenString NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, copy, readonly) NSString *accessTokenString;
|
||||
|
||||
- (id)objectForKeyedSubscript:(id)key;
|
||||
- (void)resetForAccessTokenString:(NSString *)accessTokenString;
|
||||
- (void)setObject:(id)object forKeyedSubscript:(id)key;
|
||||
|
||||
@end
|
||||
Generated
+116
@@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeActionControllerCache.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "FBSDKLikeActionController.h"
|
||||
|
||||
// after 1 day, expire the cached states
|
||||
#define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT 60 * 24
|
||||
|
||||
#define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY @"accessTokenString"
|
||||
#define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY @"items"
|
||||
|
||||
@implementation FBSDKLikeActionControllerCache
|
||||
{
|
||||
NSString *_accessTokenString;
|
||||
NSMutableDictionary *_items;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)initWithAccessTokenString:(NSString *)accessTokenString
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_accessTokenString = [accessTokenString copy];
|
||||
_items = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
FBSDK_NOT_DESIGNATED_INITIALIZER(initWithAccessTokenString:);
|
||||
return [self initWithAccessTokenString:nil];
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
NSString *accessTokenString = [decoder decodeObjectOfClass:[NSString class]
|
||||
forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY];
|
||||
if ((self = [self initWithAccessTokenString:accessTokenString])) {
|
||||
NSSet *allowedClasses = [NSSet setWithObjects:[NSDictionary class], [FBSDKLikeActionController class], nil];
|
||||
NSDictionary *items = [decoder decodeObjectOfClasses:allowedClasses
|
||||
forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY];
|
||||
_items = [[NSMutableDictionary alloc] initWithDictionary:items];
|
||||
[self _prune];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:_accessTokenString forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY];
|
||||
[encoder encodeObject:_items forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY];
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (id)objectForKeyedSubscript:(id)key
|
||||
{
|
||||
return _items[key];
|
||||
}
|
||||
|
||||
- (void)resetForAccessTokenString:(NSString *)accessTokenString
|
||||
{
|
||||
_accessTokenString = [accessTokenString copy];
|
||||
[_items removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)setObject:(id)object forKeyedSubscript:(id)key
|
||||
{
|
||||
_items[key] = object;
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_prune
|
||||
{
|
||||
NSMutableArray *keysToRemove = [[NSMutableArray alloc] init];
|
||||
[_items enumerateKeysAndObjectsUsingBlock:^(NSString *objectID,
|
||||
FBSDKLikeActionController *likeActionController,
|
||||
BOOL *stop) {
|
||||
NSDate *lastUpdateTime = likeActionController.lastUpdateTime;
|
||||
if (!lastUpdateTime ||
|
||||
([[NSDate date] timeIntervalSinceDate:lastUpdateTime] > FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT)) {
|
||||
[keysToRemove addObject:objectID];
|
||||
}
|
||||
}];
|
||||
[_items removeObjectsForKeys:keysToRemove];
|
||||
}
|
||||
|
||||
@end
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "FBSDKLikeBoxView.h"
|
||||
|
||||
@interface FBSDKLikeBoxBorderView : UIView
|
||||
|
||||
@property (nonatomic, assign) CGFloat borderCornerRadius;
|
||||
@property (nonatomic, assign) CGFloat borderWidth;
|
||||
@property (nonatomic, assign) FBSDKLikeBoxCaretPosition caretPosition;
|
||||
@property (nonatomic, assign, readonly) UIEdgeInsets contentInsets;
|
||||
@property (nonatomic, strong) UIView *contentView;
|
||||
@property (nonatomic, strong) UIColor *fillColor;
|
||||
@property (nonatomic, strong) UIColor *foregroundColor;
|
||||
|
||||
@end
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeBoxBorderView.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
#define FBSDK_LIKE_BOX_BORDER_CARET_WIDTH 6.0
|
||||
#define FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT 3.0
|
||||
#define FBSDK_LIKE_BOX_BORDER_CARET_PADDING 3.0
|
||||
#define FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING 4.0
|
||||
|
||||
@implementation FBSDKLikeBoxBorderView
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
[self _initializeContent];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [super initWithCoder:decoder])) {
|
||||
[self _initializeContent];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
||||
{
|
||||
if (![self.backgroundColor isEqual:backgroundColor]) {
|
||||
[super setBackgroundColor:backgroundColor];
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBorderCornerRadius:(CGFloat)borderCornerRadius
|
||||
{
|
||||
if (_borderCornerRadius != borderCornerRadius) {
|
||||
_borderCornerRadius = borderCornerRadius;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBorderWidth:(CGFloat)borderWidth
|
||||
{
|
||||
if (_borderWidth != borderWidth) {
|
||||
_borderWidth = borderWidth;
|
||||
[self setNeedsDisplay];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setCaretPosition:(FBSDKLikeBoxCaretPosition)caretPosition
|
||||
{
|
||||
if (_caretPosition != caretPosition) {
|
||||
_caretPosition = caretPosition;
|
||||
[self setNeedsLayout];
|
||||
[self setNeedsDisplay];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIEdgeInsets)contentInsets
|
||||
{
|
||||
UIEdgeInsets borderInsets = [self _borderInsets];
|
||||
return UIEdgeInsetsMake(borderInsets.top + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING,
|
||||
borderInsets.left + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING,
|
||||
borderInsets.bottom + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING,
|
||||
borderInsets.right + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING);
|
||||
}
|
||||
|
||||
- (void)setContentView:(UIView *)contentView
|
||||
{
|
||||
if (_contentView != contentView) {
|
||||
[_contentView removeFromSuperview];
|
||||
_contentView = contentView;
|
||||
[self addSubview:_contentView];
|
||||
[self setNeedsLayout];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFillColor:(UIColor *)fillColor
|
||||
{
|
||||
if (![_fillColor isEqual:fillColor]) {
|
||||
_fillColor = fillColor;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setForegroundColor:(UIColor *)foregroundColor
|
||||
{
|
||||
if (![_foregroundColor isEqual:foregroundColor]) {
|
||||
_foregroundColor = foregroundColor;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
return FBSDKEdgeInsetsOutsetSize(self.contentView.intrinsicContentSize, self.contentInsets);
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
self.contentView.frame = UIEdgeInsetsInsetRect(self.bounds, self.contentInsets);
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
UIEdgeInsets contentInsets = self.contentInsets;
|
||||
size = FBSDKEdgeInsetsInsetSize(size, contentInsets);
|
||||
size = [self.contentView sizeThatFits:size];
|
||||
size = FBSDKEdgeInsetsOutsetSize(size, contentInsets);
|
||||
return size;
|
||||
}
|
||||
|
||||
#pragma mark - Drawing
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
CGContextSaveGState(context);
|
||||
|
||||
// read the configuration properties
|
||||
CGRect bounds = self.bounds;
|
||||
CGFloat borderWidth = self.borderWidth;
|
||||
CGFloat borderCornerRadius = self.borderCornerRadius;
|
||||
CGFloat contentScaleFactor = self.contentScaleFactor;
|
||||
|
||||
// fill the background
|
||||
if (self.backgroundColor) {
|
||||
[self.backgroundColor setFill];
|
||||
CGContextFillRect(context, bounds);
|
||||
}
|
||||
|
||||
// configure the colors and lines
|
||||
[self.fillColor setFill];
|
||||
[self.foregroundColor setStroke];
|
||||
CGContextSetLineJoin(context, kCGLineJoinRound);
|
||||
CGContextSetLineWidth(context, borderWidth);
|
||||
|
||||
// get the frame of the box
|
||||
CGRect borderFrame = UIEdgeInsetsInsetRect(bounds, [self _borderInsets]);
|
||||
|
||||
// define the arcs for the corners
|
||||
const int start = 0;
|
||||
const int tangent = 1;
|
||||
const int end = 2;
|
||||
CGPoint topLeftArc[3] = {
|
||||
CGPointMake(CGRectGetMinX(borderFrame) + borderCornerRadius, CGRectGetMinY(borderFrame)),
|
||||
CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMinY(borderFrame)),
|
||||
CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMinY(borderFrame) + borderCornerRadius),
|
||||
};
|
||||
CGPoint bottomLeftArc[3] = {
|
||||
CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMaxY(borderFrame) - borderCornerRadius),
|
||||
CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMaxY(borderFrame)),
|
||||
CGPointMake(CGRectGetMinX(borderFrame) + borderCornerRadius, CGRectGetMaxY(borderFrame)),
|
||||
};
|
||||
CGPoint bottomRightArc[3] = {
|
||||
CGPointMake(CGRectGetMaxX(borderFrame) - borderCornerRadius, CGRectGetMaxY(borderFrame)),
|
||||
CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMaxY(borderFrame)),
|
||||
CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMaxY(borderFrame) - borderCornerRadius),
|
||||
};
|
||||
CGPoint topRightArc[3] = {
|
||||
CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMinY(borderFrame) + borderCornerRadius),
|
||||
CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMinY(borderFrame)),
|
||||
CGPointMake(CGRectGetMaxX(borderFrame) - borderCornerRadius, CGRectGetMinY(borderFrame)),
|
||||
};
|
||||
|
||||
// start a path on the context
|
||||
CGContextBeginPath(context);
|
||||
|
||||
// position the caret and decide which lines to draw
|
||||
CGPoint caretPoints[3];
|
||||
switch (self.caretPosition) {
|
||||
case FBSDKLikeBoxCaretPositionTop:
|
||||
CGContextMoveToPoint(context, topRightArc[end].x, topRightArc[end].y);
|
||||
caretPoints[0] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)),
|
||||
CGRectGetMinY(borderFrame));
|
||||
caretPoints[1] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)),
|
||||
CGRectGetMinY(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT);
|
||||
caretPoints[2] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)),
|
||||
CGRectGetMinY(borderFrame));
|
||||
CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0]));
|
||||
CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, bottomLeftArc[start].x, bottomLeftArc[start].y);
|
||||
CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, bottomRightArc[start].x, bottomRightArc[start].y);
|
||||
CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, topRightArc[start].x, topRightArc[start].y);
|
||||
CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius);
|
||||
break;
|
||||
case FBSDKLikeBoxCaretPositionLeft:
|
||||
CGContextMoveToPoint(context, topLeftArc[end].x, topLeftArc[end].y);
|
||||
caretPoints[0] = CGPointMake(CGRectGetMinX(borderFrame),
|
||||
FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)));
|
||||
caretPoints[1] = CGPointMake(CGRectGetMinX(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT,
|
||||
FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame)));
|
||||
caretPoints[2] = CGPointMake(CGRectGetMinX(borderFrame),
|
||||
FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)));
|
||||
CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0]));
|
||||
CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, bottomRightArc[start].x, bottomRightArc[start].y);
|
||||
CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, topRightArc[start].x, topRightArc[start].y);
|
||||
CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, topLeftArc[start].x, topLeftArc[start].y);
|
||||
CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius);
|
||||
break;
|
||||
case FBSDKLikeBoxCaretPositionBottom:
|
||||
CGContextMoveToPoint(context, bottomLeftArc[end].x, bottomLeftArc[end].y);
|
||||
caretPoints[0] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)),
|
||||
CGRectGetMaxY(borderFrame));
|
||||
caretPoints[1] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)),
|
||||
CGRectGetMaxY(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT);
|
||||
caretPoints[2] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)),
|
||||
CGRectGetMaxY(borderFrame));
|
||||
CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0]));
|
||||
CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, topRightArc[start].x, topRightArc[start].y);
|
||||
CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, topLeftArc[start].x, topLeftArc[start].y);
|
||||
CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, bottomLeftArc[start].x, bottomLeftArc[start].y);
|
||||
CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius);
|
||||
break;
|
||||
case FBSDKLikeBoxCaretPositionRight:
|
||||
CGContextMoveToPoint(context, bottomRightArc[end].x, bottomRightArc[end].y);
|
||||
caretPoints[0] = CGPointMake(CGRectGetMaxX(borderFrame),
|
||||
FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)));
|
||||
caretPoints[1] = CGPointMake(CGRectGetMaxX(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT,
|
||||
FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame)));
|
||||
caretPoints[2] = CGPointMake(CGRectGetMaxX(borderFrame),
|
||||
FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)));
|
||||
CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0]));
|
||||
CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, topLeftArc[start].x, topLeftArc[start].y);
|
||||
CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, bottomLeftArc[start].x, bottomLeftArc[start].y);
|
||||
CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius);
|
||||
CGContextAddLineToPoint(context, bottomRightArc[start].x, bottomRightArc[start].y);
|
||||
CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius);
|
||||
break;
|
||||
}
|
||||
|
||||
// close and draw now that we have it all
|
||||
CGContextClosePath(context);
|
||||
CGContextDrawPath(context, kCGPathFillStroke);
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (UIEdgeInsets)_borderInsets
|
||||
{
|
||||
// inset the border bounds by 1/2 of the border width, since it is drawn split between inside and outside of the path
|
||||
CGFloat scale = self.contentScaleFactor;
|
||||
CGFloat halfBorderWidth = FBSDKPointsForScreenPixels(ceilf, scale, self.borderWidth / 2);
|
||||
UIEdgeInsets borderInsets = UIEdgeInsetsMake(halfBorderWidth, halfBorderWidth, halfBorderWidth, halfBorderWidth);
|
||||
|
||||
// adjust the insets for the caret position
|
||||
switch (self.caretPosition) {
|
||||
case FBSDKLikeBoxCaretPositionTop:{
|
||||
borderInsets.top += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING;
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeBoxCaretPositionLeft:{
|
||||
borderInsets.left += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING;
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeBoxCaretPositionBottom:{
|
||||
borderInsets.bottom += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING;
|
||||
break;
|
||||
}
|
||||
case FBSDKLikeBoxCaretPositionRight:{
|
||||
borderInsets.right += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return borderInsets;
|
||||
}
|
||||
|
||||
- (void)_initializeContent
|
||||
{
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.borderCornerRadius = 3.0;
|
||||
self.borderWidth = 1.0;
|
||||
self.contentMode = UIViewContentModeRedraw;
|
||||
self.fillColor = [UIColor whiteColor];
|
||||
self.foregroundColor = FBSDKUIColorWithRGB(0x6A, 0x71, 0x80);
|
||||
self.opaque = NO;
|
||||
}
|
||||
|
||||
@end
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/*!
|
||||
@typedef NS_ENUM(NSUInteger, FBSDKLikeBoxCaretPosition)
|
||||
|
||||
@abstract Specifies the position of the caret relative to the box.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, FBSDKLikeBoxCaretPosition)
|
||||
{
|
||||
/*! The caret is on the top of the box. */
|
||||
FBSDKLikeBoxCaretPositionTop,
|
||||
/*! The caret is on the left of the box. */
|
||||
FBSDKLikeBoxCaretPositionLeft,
|
||||
/*! The caret is on the bottom of the box. */
|
||||
FBSDKLikeBoxCaretPositionBottom,
|
||||
/*! The caret is on the right of the box. */
|
||||
FBSDKLikeBoxCaretPositionRight,
|
||||
};
|
||||
|
||||
@interface FBSDKLikeBoxView : UIView
|
||||
|
||||
@property (nonatomic, assign) FBSDKLikeBoxCaretPosition caretPosition;
|
||||
@property (nonatomic, copy) NSString *text;
|
||||
|
||||
@end
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeBoxView.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKLikeBoxBorderView.h"
|
||||
|
||||
@implementation FBSDKLikeBoxView
|
||||
{
|
||||
FBSDKLikeBoxBorderView *_borderView;
|
||||
UILabel *_likeCountLabel;
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if ((self = [super initWithFrame:frame])) {
|
||||
[self _initializeContent];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
if ((self = [super initWithCoder:decoder])) {
|
||||
[self _initializeContent];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setCaretPosition:(FBSDKLikeBoxCaretPosition)caretPosition
|
||||
{
|
||||
if (_caretPosition != caretPosition) {
|
||||
_caretPosition = caretPosition;
|
||||
_borderView.caretPosition = _caretPosition;
|
||||
[self setNeedsLayout];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)text
|
||||
{
|
||||
return _likeCountLabel.text;
|
||||
}
|
||||
|
||||
- (void)setText:(NSString *)text
|
||||
{
|
||||
if (![_likeCountLabel.text isEqualToString:text]) {
|
||||
_likeCountLabel.text = text;
|
||||
[self setNeedsLayout];
|
||||
[self invalidateIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
return _borderView.intrinsicContentSize;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
CGRect bounds = self.bounds;
|
||||
_borderView.frame = bounds;
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
return [_borderView sizeThatFits:size];
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (void)_initializeContent
|
||||
{
|
||||
_borderView = [[FBSDKLikeBoxBorderView alloc] initWithFrame:CGRectZero];
|
||||
[self addSubview:_borderView];
|
||||
|
||||
_likeCountLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
_likeCountLabel.font = [UIFont systemFontOfSize:11.0];
|
||||
_likeCountLabel.textAlignment = NSTextAlignmentCenter;
|
||||
_likeCountLabel.textColor = FBSDKUIColorWithRGB(0x6A, 0x71, 0x80);
|
||||
_borderView.contentView = _likeCountLabel;
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKLikeActionController.h"
|
||||
#import "FBSDKLikeButton.h"
|
||||
|
||||
@interface FBSDKLikeButton () <FBSDKButtonImpressionTracking>
|
||||
|
||||
@property (nonatomic, strong, readwrite) FBSDKLikeActionController *likeActionController;
|
||||
|
||||
@end
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
@interface FBSDKLikeButtonPopWAV : FBSDKAudioResourceLoader
|
||||
@end
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeButtonPopWAV.h"
|
||||
|
||||
@implementation FBSDKLikeButtonPopWAV
|
||||
|
||||
+ (NSString *)name
|
||||
{
|
||||
return @"FBSDKLikeButtonPop.wav";
|
||||
}
|
||||
|
||||
+ (NSData *)data
|
||||
{
|
||||
const Byte bytes[] = {
|
||||
0x52, 0x49, 0x46, 0x46, 0xfc, 0x57, 0x02, 0x00, 0x57, 0x41, 0x56, 0x45, 0x4a, 0x55, 0x4e, 0x4b, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x65, 0x78, 0x74, 0x5a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x72, 0x6f, 0x20, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x68, 0x72, 0x72, 0x48, 0x37, 0x38, 0x21, 0x54, 0x66, 0x61, 0x61, 0x61, 0x61, 0x47, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x31, 0x2d, 0x31, 0x00, 0x31, 0x35, 0x3a, 0x32, 0x38, 0x3a, 0x30, 0x31, 0xf7, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6d, 0x74, 0x20, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0xee, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e, 0x66, 0x10, 0x00, 0x00, 0x00, 0x70, 0xe2, 0xe6, 0xc4, 0xdb, 0x13, 0xcf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x6c, 0x6d, 0x31, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0Line truncated
|
||||
NSUInteger length = sizeof(bytes) / sizeof(Byte);
|
||||
return [NSData dataWithBytesNoCopy:(void *)bytes length:length freeWhenDone:NO];
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKLikeControl.h"
|
||||
|
||||
@interface FBSDKLikeControl ()
|
||||
|
||||
- (NSDictionary *)analyticsParameters;
|
||||
|
||||
@end
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKLikeObjectType.h>
|
||||
|
||||
@protocol FBSDKLikeDialogDelegate;
|
||||
|
||||
@interface FBSDKLikeDialog : NSObject
|
||||
|
||||
+ (instancetype)likeWithObjectID:(NSString *)objectID
|
||||
objectType:(FBSDKLikeObjectType)objectType
|
||||
delegate:(id<FBSDKLikeDialogDelegate>)delegate;
|
||||
|
||||
@property (nonatomic, weak) id<FBSDKLikeDialogDelegate> delegate;
|
||||
@property (nonatomic, copy) NSString *objectID;
|
||||
@property (nonatomic, assign) FBSDKLikeObjectType objectType;
|
||||
@property (nonatomic, assign) BOOL shouldFailOnDataError;
|
||||
@property (nonatomic, weak) UIViewController *fromViewController;
|
||||
|
||||
- (BOOL)canLike;
|
||||
- (BOOL)like;
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef;
|
||||
|
||||
@end
|
||||
|
||||
@protocol FBSDKLikeDialogDelegate <NSObject>
|
||||
|
||||
- (void)likeDialog:(FBSDKLikeDialog *)likeDialog didCompleteWithResults:(NSDictionary *)results;
|
||||
- (void)likeDialog:(FBSDKLikeDialog *)likeDialog didFailWithError:(NSError *)error;
|
||||
|
||||
@end
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKLikeDialog.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareDefines.h"
|
||||
#import "FBSDKShareError.h"
|
||||
|
||||
@implementation FBSDKLikeDialog
|
||||
|
||||
#define FBSDK_LIKE_METHOD_MIN_VERSION @"20140410"
|
||||
#define FBSDK_LIKE_METHOD_NAME @"like"
|
||||
#define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_LIKE @"like"
|
||||
#define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_UNLIKE @"unlike"
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
if ([FBSDKLikeDialog class] == self) {
|
||||
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
+ (instancetype)likeWithObjectID:(NSString *)objectID
|
||||
objectType:(FBSDKLikeObjectType)objectType
|
||||
delegate:(id<FBSDKLikeDialogDelegate>)delegate
|
||||
{
|
||||
FBSDKLikeDialog *dialog = [[self alloc] init];
|
||||
dialog.objectID = objectID;
|
||||
dialog.objectType = objectType;
|
||||
dialog.delegate = delegate;
|
||||
[dialog like];
|
||||
return dialog;
|
||||
}
|
||||
|
||||
#pragma mark - Public Methods
|
||||
|
||||
- (BOOL)canLike
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)like
|
||||
{
|
||||
NSError *error;
|
||||
if (![self canLike]) {
|
||||
error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode
|
||||
message:@"Like dialog is not available."];
|
||||
[_delegate likeDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
if (![self validateWithError:&error]) {
|
||||
[_delegate likeDialog:self didFailWithError:error];
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:self.objectID forKey:@"object_id"];
|
||||
[FBSDKInternalUtility dictionary:parameters
|
||||
setObject:NSStringFromFBSDKLikeObjectType(self.objectType)
|
||||
forKey:@"object_type"];
|
||||
FBSDKBridgeAPIRequest * webRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb
|
||||
scheme:FBSDK_SHARE_JS_DIALOG_SCHEME
|
||||
methodName:FBSDK_LIKE_METHOD_NAME
|
||||
methodVersion:nil
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) {
|
||||
[self _handleCompletionWithDialogResults:response.responseParameters error:response.error];
|
||||
};
|
||||
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
BOOL useSafariViewController = [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameLike];
|
||||
if ([self _canLikeNative]) {
|
||||
FBSDKBridgeAPIRequest *nativeRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative
|
||||
scheme:FBSDK_CANOPENURL_FACEBOOK
|
||||
methodName:FBSDK_LIKE_METHOD_NAME
|
||||
methodVersion:FBSDK_LIKE_METHOD_MIN_VERSION
|
||||
parameters:parameters
|
||||
userInfo:nil];
|
||||
void (^networkCompletionBlock)(FBSDKBridgeAPIResponse *) = ^(FBSDKBridgeAPIResponse *response) {
|
||||
if (response.error.code == FBSDKAppVersionUnsupportedErrorCode) {
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webRequest
|
||||
useSafariViewController:useSafariViewController
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:completionBlock];
|
||||
} else {
|
||||
completionBlock(response);
|
||||
}
|
||||
};
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:nativeRequest
|
||||
useSafariViewController:useSafariViewController
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:networkCompletionBlock];
|
||||
} else {
|
||||
[[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webRequest
|
||||
useSafariViewController:useSafariViewController
|
||||
fromViewController:self.fromViewController
|
||||
completionBlock:completionBlock];
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (![self.objectID length]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"objectID" message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
- (BOOL)_canLikeNative
|
||||
{
|
||||
FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration];
|
||||
BOOL useNativeDialog = [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameLike];
|
||||
return (useNativeDialog && [FBSDKInternalUtility isFacebookAppInstalled]);
|
||||
}
|
||||
|
||||
- (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error
|
||||
{
|
||||
if (!_delegate) {
|
||||
return;
|
||||
}
|
||||
NSString *completionGesture = results[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY];
|
||||
if (completionGesture && !error) {
|
||||
[_delegate likeDialog:self didCompleteWithResults:[results copy]];
|
||||
} else {
|
||||
[_delegate likeDialog:self didFailWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
@interface FBSDKMessengerIcon : FBSDKIcon
|
||||
|
||||
@end
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKMessengerIcon.h"
|
||||
|
||||
@implementation FBSDKMessengerIcon
|
||||
|
||||
- (CGPathRef)pathWithSize:(CGSize)size
|
||||
{
|
||||
CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / 61.0, size.height / 61.0);
|
||||
const CGAffineTransform *transform = &transformValue;
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
CGPathMoveToPoint(path, transform, 30.001, 0.962);
|
||||
CGPathAddCurveToPoint(path, transform, 13.439, 0.962, 0.014, 13.462, 0.014, 28.882);
|
||||
CGPathAddCurveToPoint(path, transform, 0.014, 37.165, 3.892, 44.516, 10.046, 49.549);
|
||||
CGPathAddLineToPoint(path, transform, 10.046, 61.176);
|
||||
CGPathAddLineToPoint(path, transform, 19.351, 54.722);
|
||||
CGPathAddCurveToPoint(path, transform, 22.662, 55.870, 26.250, 56.502, 30.002, 56.502);
|
||||
CGPathAddCurveToPoint(path, transform, 46.565, 56.502, 59.990, 44.301, 59.990, 28.882);
|
||||
CGPathAddCurveToPoint(path, transform, 59.989, 13.462, 46.564, 0.962, 30.001, 0.962);
|
||||
CGPathCloseSubpath(path);
|
||||
CGPathMoveToPoint(path, transform, 33.159, 37.473);
|
||||
CGPathAddLineToPoint(path, transform, 25.403, 29.484);
|
||||
CGPathAddLineToPoint(path, transform, 10.467, 37.674);
|
||||
CGPathAddLineToPoint(path, transform, 26.843, 20.445);
|
||||
CGPathAddLineToPoint(path, transform, 34.599, 28.433);
|
||||
CGPathAddLineToPoint(path, transform, 49.535, 20.244);
|
||||
CGPathAddLineToPoint(path, transform, 33.159, 37.473);
|
||||
CGPathCloseSubpath(path);
|
||||
CGPathRef result = CGPathCreateCopy(path);
|
||||
CGPathRelease(path);
|
||||
return CFAutorelease(result);
|
||||
}
|
||||
|
||||
@end
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define FBSDK_SHARE_JS_DIALOG_SCHEME @"web"
|
||||
#define FBSDK_SHARE_METHOD_NAME @"share"
|
||||
#define FBSDK_SHARE_OPEN_GRAPH_METHOD_NAME @"ogshare"
|
||||
#define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY @"completionGesture"
|
||||
#define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL @"cancel"
|
||||
#define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST @"post"
|
||||
#define FBSDK_SHARE_RESULT_DID_COMPLETE_KEY @"didComplete"
|
||||
#define FBSDK_SHARE_RESULT_POST_ID_KEY @"postId"
|
||||
#define FBSDK_SHARE_VIDEO_END_OFFSET @"end_offset"
|
||||
#define FBSDK_SHARE_VIDEO_FILE_CHUNK @"video_file_chunk"
|
||||
#define FBSDK_SHARE_VIDEO_ID @"video_id"
|
||||
#define FBSDK_SHARE_VIDEO_SIZE @"file_size"
|
||||
#define FBSDK_SHARE_VIDEO_START_OFFSET @"start_offset"
|
||||
#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE @"upload_phase"
|
||||
#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH @"finish"
|
||||
#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START @"start"
|
||||
#define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_TRANSFER @"transfer"
|
||||
#define FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID @"upload_session_id"
|
||||
#define FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS @"success"
|
||||
#define FBSDK_SHARE_WEB_PARAM_POST_ID_KEY @"post_id"
|
||||
#define FBSDK_SHARE_WEB_SCHEME @"https"
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
|
||||
@interface FBSDKShareError : FBSDKError
|
||||
|
||||
@end
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareError.h"
|
||||
|
||||
#import "FBSDKShareConstants.h"
|
||||
|
||||
@implementation FBSDKShareError
|
||||
|
||||
+ (NSString *)errorDomain
|
||||
{
|
||||
return FBSDKShareErrorDomain;
|
||||
}
|
||||
|
||||
@end
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareKit.h>
|
||||
|
||||
#import "FBSDKShareDefines.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareOpenGraphValueContainer+Internal.h"
|
||||
#import "FBSDKShareUtility.h"
|
||||
#import "FBSDKVideoUploader.h"
|
||||
Generated
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareLinkContent.h"
|
||||
|
||||
@interface FBSDKShareLinkContent ()
|
||||
|
||||
// Deprecated parameters for Feed Dialog - for usage with Unity only.
|
||||
@property (nonatomic, copy) NSDictionary *feedParameters;
|
||||
|
||||
@end
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphValueContainer.h>
|
||||
|
||||
@interface FBSDKShareOpenGraphValueContainer ()
|
||||
|
||||
- (NSDictionary *)allProperties;
|
||||
- (BOOL)isEqualToShareOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object;
|
||||
- (BOOL)requireKeyNamespace;
|
||||
|
||||
@end
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareLinkContent.h>
|
||||
#import <FBSDKShareKit/FBSDKShareOpenGraphContent.h>
|
||||
#import <FBSDKShareKit/FBSDKSharePhotoContent.h>
|
||||
#import <FBSDKShareKit/FBSDKShareVideoContent.h>
|
||||
#import <FBSDKShareKit/FBSDKSharingContent.h>
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#import <FBSDKShareKit/FBSDKAppInviteContent.h>
|
||||
#import <FBSDKShareKit/FBSDKGameRequestContent.h>
|
||||
#endif
|
||||
|
||||
@interface FBSDKShareUtility : NSObject
|
||||
|
||||
+ (void)assertCollection:(id<NSFastEnumeration>)collection ofClass:itemClass name:(NSString *)name;
|
||||
+ (void)assertOpenGraphKey:(id)key requireNamespace:(BOOL)requireNamespace;
|
||||
+ (void)assertOpenGraphValue:(id)value;
|
||||
+ (void)assertOpenGraphValues:(NSDictionary *)dictionary requireKeyNamespace:(BOOL)requireKeyNamespace;
|
||||
+ (id)convertOpenGraphValue:(id)value;
|
||||
+ (BOOL)buildWebShareContent:(id<FBSDKSharingContent>)content
|
||||
methodName:(NSString *__autoreleasing *)methodNameRef
|
||||
parameters:(NSDictionary *__autoreleasing *)parametersRef
|
||||
error:(NSError *__autoreleasing *)errorRef;
|
||||
+ (NSDictionary *)convertOpenGraphValues:(NSDictionary *)dictionary;
|
||||
+ (NSDictionary *)feedShareDictionaryForContent:(id<FBSDKSharingContent>)content;
|
||||
+ (NSDictionary *)parametersForShareContent:(id<FBSDKSharingContent>)shareContent
|
||||
shouldFailOnDataError:(BOOL)shouldFailOnDataError;
|
||||
+ (void)testShareContent:(id<FBSDKSharingContent>)shareContent
|
||||
containsMedia:(BOOL *)containsMediaRef
|
||||
containsPhotos:(BOOL *)containsPhotosRef;
|
||||
+ (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef;
|
||||
+ (BOOL)validateShareContent:(id<FBSDKSharingContent>)shareContent error:(NSError *__autoreleasing *)errorRef;
|
||||
+ (BOOL)validateShareLinkContent:(FBSDKShareLinkContent *)linkContent error:(NSError *__autoreleasing *)errorRef;
|
||||
+ (BOOL)validateShareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent
|
||||
error:(NSError *__autoreleasing *)errorRef;
|
||||
+ (BOOL)validateSharePhotoContent:(FBSDKSharePhotoContent *)photoContent error:(NSError *__autoreleasing *)errorRef;
|
||||
+ (NSString *)getOpenGraphNameAndNamespaceFromFullName:(NSString *)fullName namespace:(NSString **)namespace;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
+ (BOOL)validateAppInviteContent:(FBSDKAppInviteContent *)appInviteContent error:(NSError *__autoreleasing *)errorRef;
|
||||
+ (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef;
|
||||
#endif
|
||||
@end
|
||||
+732
@@ -0,0 +1,732 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKShareUtility.h"
|
||||
|
||||
#import "FBSDKCoreKit+Internal.h"
|
||||
#import "FBSDKShareConstants.h"
|
||||
#import "FBSDKShareError.h"
|
||||
#import "FBSDKShareLinkContent+Internal.h"
|
||||
#import "FBSDKShareOpenGraphContent.h"
|
||||
#import "FBSDKShareOpenGraphObject.h"
|
||||
#import "FBSDKSharePhoto.h"
|
||||
#import "FBSDKSharePhotoContent.h"
|
||||
#import "FBSDKShareVideo.h"
|
||||
#import "FBSDKShareVideoContent.h"
|
||||
#import "FBSDKSharingContent.h"
|
||||
|
||||
@implementation FBSDKShareUtility
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (void)assertCollection:(id<NSFastEnumeration>)collection ofClass:itemClass name:(NSString *)name
|
||||
{
|
||||
for (id item in collection) {
|
||||
if (![item isKindOfClass:itemClass]) {
|
||||
NSString *reason = [[NSString alloc] initWithFormat:
|
||||
@"Invalid value found in %@: %@ - %@",
|
||||
name,
|
||||
item,
|
||||
collection];
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)assertOpenGraphKey:(id)key requireNamespace:(BOOL)requireNamespace
|
||||
{
|
||||
if (![key isKindOfClass:[NSString class]]) {
|
||||
NSString *reason = [[NSString alloc] initWithFormat:@"Invalid key found in Open Graph dictionary: %@", key];
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
|
||||
}
|
||||
if (!requireNamespace) {
|
||||
return;
|
||||
}
|
||||
NSArray *components = [key componentsSeparatedByString:@":"];
|
||||
if ([components count] < 2) {
|
||||
NSString *reason = [[NSString alloc] initWithFormat:@"Open Graph keys must be namespaced: %@", key];
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
|
||||
}
|
||||
for (NSString *component in components) {
|
||||
if (![component length]) {
|
||||
NSString *reason = [[NSString alloc] initWithFormat:@"Invalid key found in Open Graph dictionary: %@", key];
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)assertOpenGraphValue:(id)value
|
||||
{
|
||||
if ([self _isOpenGraphValue:value]) {
|
||||
return;
|
||||
}
|
||||
if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
[self assertOpenGraphValues:(NSDictionary *)value requireKeyNamespace:YES];
|
||||
return;
|
||||
}
|
||||
if ([value isKindOfClass:[NSArray class]]) {
|
||||
for (id subValue in (NSArray *)value) {
|
||||
[self assertOpenGraphValue:subValue];
|
||||
}
|
||||
return;
|
||||
}
|
||||
NSString *reason = [[NSString alloc] initWithFormat:@"Invalid Open Graph value found: %@", value];
|
||||
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
|
||||
}
|
||||
|
||||
+ (void)assertOpenGraphValues:(NSDictionary *)dictionary requireKeyNamespace:(BOOL)requireKeyNamespace
|
||||
{
|
||||
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
|
||||
[self assertOpenGraphKey:key requireNamespace:requireKeyNamespace];
|
||||
[self assertOpenGraphValue:value];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (BOOL)buildWebShareContent:(id<FBSDKSharingContent>)content
|
||||
methodName:(NSString *__autoreleasing *)methodNameRef
|
||||
parameters:(NSDictionary *__autoreleasing *)parametersRef
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
NSString *methodName = nil;
|
||||
NSDictionary *parameters = nil;
|
||||
if ([content isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
methodName = @"share_open_graph";
|
||||
FBSDKShareOpenGraphContent *openGraphContent = (FBSDKShareOpenGraphContent *)content;
|
||||
FBSDKShareOpenGraphAction *action = openGraphContent.action;
|
||||
NSDictionary *properties = [self _convertOpenGraphValueContainer:action requireNamespace:NO];
|
||||
NSString *propertiesJSON = [FBSDKInternalUtility JSONStringForObject:properties
|
||||
error:errorRef
|
||||
invalidObjectHandler:NULL];
|
||||
parameters = @{
|
||||
@"action_type": action.actionType,
|
||||
@"action_properties": propertiesJSON,
|
||||
};
|
||||
} else if ([content isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
FBSDKShareLinkContent *linkContent = (FBSDKShareLinkContent *)content;
|
||||
methodName = @"share";
|
||||
if (linkContent.contentURL != nil) {
|
||||
parameters = @{ @"href": linkContent.contentURL.absoluteString };
|
||||
}
|
||||
}
|
||||
if (methodNameRef != NULL) {
|
||||
*methodNameRef = methodName;
|
||||
}
|
||||
if (parametersRef != NULL) {
|
||||
*parametersRef = parameters;
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (id)convertOpenGraphValue:(id)value
|
||||
{
|
||||
if ([self _isOpenGraphValue:value]) {
|
||||
return value;
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *properties = (NSDictionary *)value;
|
||||
if ([FBSDKTypeUtility stringValue:properties[@"type"]]) {
|
||||
return [FBSDKShareOpenGraphObject objectWithProperties:properties];
|
||||
} else {
|
||||
NSURL *imageURL = [FBSDKTypeUtility URLValue:properties[@"url"]];
|
||||
if (imageURL) {
|
||||
FBSDKSharePhoto *sharePhoto = [FBSDKSharePhoto photoWithImageURL:imageURL
|
||||
userGenerated:[FBSDKTypeUtility boolValue:properties[@"user_generated"]]];
|
||||
sharePhoto.caption = [FBSDKTypeUtility stringValue:properties[@"caption"]];
|
||||
return sharePhoto;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
} else if ([value isKindOfClass:[NSArray class]]) {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||
for (id subValue in (NSArray *)value) {
|
||||
[FBSDKInternalUtility array:array addObject:[self convertOpenGraphValue:subValue]];
|
||||
}
|
||||
return [array copy];
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSDictionary *)convertOpenGraphValues:(NSDictionary *)dictionary
|
||||
{
|
||||
NSMutableDictionary *convertedDictionary = [[NSMutableDictionary alloc] init];
|
||||
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||
[FBSDKInternalUtility dictionary:convertedDictionary setObject:[self convertOpenGraphValue:obj] forKey:key];
|
||||
}];
|
||||
return [convertedDictionary copy];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)feedShareDictionaryForContent:(id<FBSDKSharingContent>)content
|
||||
{
|
||||
NSMutableDictionary *parameters = nil;
|
||||
if ([content isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
FBSDKShareLinkContent *linkContent = (FBSDKShareLinkContent *)content;
|
||||
parameters = [[NSMutableDictionary alloc] initWithDictionary:linkContent.feedParameters];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentDescription forKey:@"description"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL forKey:@"link"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentTitle forKey:@"name"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.imageURL forKey:@"picture"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.ref forKey:@"ref"];
|
||||
}
|
||||
return [parameters copy];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)parametersForShareContent:(id<FBSDKSharingContent>)shareContent
|
||||
shouldFailOnDataError:(BOOL)shouldFailOnDataError
|
||||
{
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
[self _addToParameters:parameters forShareContent:shareContent];
|
||||
parameters[@"dataFailuresFatal"] = @(shouldFailOnDataError);
|
||||
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
[self _addToParameters:parameters forShareLinkContent:(FBSDKShareLinkContent *)shareContent];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
[self _addToParameters:parameters forSharePhotoContent:(FBSDKSharePhotoContent *)shareContent];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
[self _addToParameters:parameters forShareVideoContent:(FBSDKShareVideoContent *)shareContent];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
[self _addToParameters:parameters forShareOpenGraphContent:(FBSDKShareOpenGraphContent *)shareContent];
|
||||
}
|
||||
return [parameters copy];
|
||||
}
|
||||
|
||||
+ (void)testShareContent:(id<FBSDKSharingContent>)shareContent
|
||||
containsMedia:(BOOL *)containsMediaRef
|
||||
containsPhotos:(BOOL *)containsPhotosRef
|
||||
{
|
||||
BOOL containsMedia = NO;
|
||||
BOOL containsPhotos = NO;
|
||||
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
containsMedia = NO;
|
||||
containsPhotos = NO;
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
containsMedia = YES;
|
||||
containsPhotos = NO;
|
||||
} else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
[self _testObject:((FBSDKSharePhotoContent *)shareContent).photos
|
||||
containsMedia:&containsMedia
|
||||
containsPhotos:&containsPhotos];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
[self _testOpenGraphValueContainer:((FBSDKShareOpenGraphContent *)shareContent).action
|
||||
containsMedia:&containsMedia
|
||||
containsPhotos:&containsPhotos];
|
||||
}
|
||||
if (containsMediaRef != NULL) {
|
||||
*containsMediaRef = containsMedia;
|
||||
}
|
||||
if (containsPhotosRef != NULL) {
|
||||
*containsPhotosRef = containsPhotos;
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
+ (BOOL)validateAppInviteContent:(FBSDKAppInviteContent *)appInviteContent error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
return ([self _validateRequiredValue:appInviteContent name:@"content" error:errorRef] &&
|
||||
[self _validateRequiredValue:appInviteContent.appLinkURL name:@"appLinkURL" error:errorRef] &&
|
||||
[self _validateNetworkURL:appInviteContent.appLinkURL name:@"appLinkURL" error:errorRef] &&
|
||||
[self _validateNetworkURL:appInviteContent.appInvitePreviewImageURL name:@"appInvitePreviewImageURL" error:errorRef]);
|
||||
}
|
||||
#endif
|
||||
|
||||
+ (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
FBSDKShareVideo *video = videoContent.video;
|
||||
NSURL *videoURL = video.videoURL;
|
||||
if (!videoURL || [[videoURL.scheme lowercaseString] isEqualToString:@"assets-library"]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
} else {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:videoURL message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
+ (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (![self _validateRequiredValue:gameRequestContent name:@"content" error:errorRef]
|
||||
|| ![self _validateRequiredValue:gameRequestContent.message name:@"message" error:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
BOOL mustHaveobjectID = gameRequestContent.actionType == FBSDKGameRequestActionTypeSend
|
||||
|| gameRequestContent.actionType == FBSDKGameRequestActionTypeAskFor;
|
||||
BOOL hasobjectID = [gameRequestContent.objectID length] > 0;
|
||||
if (mustHaveobjectID ^ hasobjectID) {
|
||||
if (errorRef != NULL) {
|
||||
NSString *message = @"The objectID is required when the actionType is either send or askfor.";
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"objectID" message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
BOOL hasTo = [gameRequestContent.recipients count] > 0;
|
||||
BOOL hasFilters = gameRequestContent.filters != FBSDKGameRequestFilterNone;
|
||||
BOOL hasSuggestions = [gameRequestContent.recipientSuggestions count] > 0;
|
||||
if (hasTo && hasFilters) {
|
||||
if (errorRef != NULL) {
|
||||
NSString *message = @"Cannot specify to and filters at the same time.";
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"recipients" value:gameRequestContent.recipients message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (hasTo && hasSuggestions) {
|
||||
if (errorRef != NULL) {
|
||||
NSString *message = @"Cannot specify to and suggestions at the same time.";
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"recipients" value:gameRequestContent.recipients message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (hasFilters && hasSuggestions) {
|
||||
if (errorRef != NULL) {
|
||||
NSString *message = @"Cannot specify filters and suggestions at the same time.";
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"recipientSuggestions" value:gameRequestContent.recipientSuggestions message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([gameRequestContent.data length] > 255) {
|
||||
if (errorRef != NULL) {
|
||||
NSString *message = @"The data cannot be longer than 255 characters";
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"data" value:gameRequestContent.data message:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
|
||||
return [self _validateArgumentWithName:@"actionType"
|
||||
value:gameRequestContent.actionType
|
||||
isIn:@[@(FBSDKGameRequestActionTypeNone),
|
||||
@(FBSDKGameRequestActionTypeSend),
|
||||
@(FBSDKGameRequestActionTypeAskFor),
|
||||
@(FBSDKGameRequestActionTypeTurn)]
|
||||
error:errorRef]
|
||||
&& [self _validateArgumentWithName:@"filters"
|
||||
value:gameRequestContent.filters
|
||||
isIn:@[@(FBSDKGameRequestFilterNone),
|
||||
@(FBSDKGameRequestFilterAppUsers),
|
||||
@(FBSDKGameRequestFilterAppNonUsers)]
|
||||
error:errorRef];
|
||||
}
|
||||
#endif
|
||||
|
||||
+ (BOOL)validateShareContent:(id<FBSDKSharingContent>)shareContent error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (![self _validateRequiredValue:shareContent name:@"shareContent" error:errorRef]) {
|
||||
return NO;
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
|
||||
return [self validateShareLinkContent:(FBSDKShareLinkContent *)shareContent error:errorRef];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
|
||||
return [self validateSharePhotoContent:(FBSDKSharePhotoContent *)shareContent error:errorRef];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
|
||||
return [self validateShareVideoContent:(FBSDKShareVideoContent *)shareContent error:errorRef];
|
||||
} else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
return [self validateShareOpenGraphContent:(FBSDKShareOpenGraphContent *)shareContent error:errorRef];
|
||||
} else {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)validateShareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
FBSDKShareOpenGraphAction *action = openGraphContent.action;
|
||||
NSString *previewPropertyName = openGraphContent.previewPropertyName;
|
||||
id object = action[previewPropertyName];
|
||||
return ([self _validateRequiredValue:openGraphContent name:@"shareContent" error:errorRef] &&
|
||||
[self _validateRequiredValue:action name:@"action" error:errorRef] &&
|
||||
[self _validateRequiredValue:previewPropertyName name:@"previewPropertyName" error:errorRef] &&
|
||||
[self _validateRequiredValue:object name:previewPropertyName error:errorRef]);
|
||||
}
|
||||
|
||||
+ (BOOL)validateSharePhotoContent:(FBSDKSharePhotoContent *)photoContent error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
NSArray *photos = photoContent.photos;
|
||||
if (![self _validateRequiredValue:photoContent name:@"shareContent" error:errorRef] ||
|
||||
![self _validateArray:photos minCount:1 maxCount:6 name:@"photos" error:errorRef]) {
|
||||
return NO;
|
||||
}
|
||||
for (FBSDKSharePhoto *photo in photos) {
|
||||
if (!photo.image) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"photos"
|
||||
value:photos
|
||||
message:@"photos must have UIImages"];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)validateShareLinkContent:(FBSDKShareLinkContent *)linkContent error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
return ([self _validateRequiredValue:linkContent name:@"shareContent" error:errorRef] &&
|
||||
[self _validateNetworkURL:linkContent.contentURL name:@"contentURL" error:errorRef] &&
|
||||
[self _validateNetworkURL:linkContent.imageURL name:@"imageURL" error:errorRef]);
|
||||
}
|
||||
|
||||
+ (BOOL)validateShareVideoContent:(FBSDKShareVideoContent *)videoContent error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
FBSDKShareVideo *video = videoContent.video;
|
||||
NSURL *videoURL = video.videoURL;
|
||||
return ([self _validateRequiredValue:videoContent name:@"videoContent" error:errorRef] &&
|
||||
[self _validateRequiredValue:video name:@"video" error:errorRef] &&
|
||||
[self _validateRequiredValue:videoURL name:@"videoURL" error:errorRef]);
|
||||
}
|
||||
|
||||
#pragma mark - Object Lifecycle
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
FBSDK_NO_DESIGNATED_INITIALIZER();
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark - Helper Methods
|
||||
|
||||
+ (void)_addToParameters:(NSMutableDictionary *)parameters forShareContent:(id<FBSDKSharingContent>)shareContent
|
||||
{
|
||||
if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
|
||||
FBSDKShareOpenGraphAction *action = ((FBSDKShareOpenGraphContent *)shareContent).action;
|
||||
[action setArray:shareContent.peopleIDs forKey:@"tags"];
|
||||
[action setString:shareContent.placeID forKey:@"place"];
|
||||
[action setString:shareContent.ref forKey:@"ref"];
|
||||
} else {
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:shareContent.peopleIDs forKey:@"tags"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:shareContent.placeID forKey:@"place"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:shareContent.ref forKey:@"ref"];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)_addToParameters:(NSMutableDictionary *)parameters
|
||||
forShareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent
|
||||
{
|
||||
NSString *previewPropertyName = [self getOpenGraphNameAndNamespaceFromFullName:openGraphContent.previewPropertyName namespace:nil];
|
||||
[FBSDKInternalUtility dictionary:parameters
|
||||
setObject:previewPropertyName
|
||||
forKey:@"previewPropertyName"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:openGraphContent.action.actionType forKey:@"actionType"];
|
||||
[FBSDKInternalUtility dictionary:parameters
|
||||
setObject:[self _convertOpenGraphValueContainer:openGraphContent.action requireNamespace:NO]
|
||||
forKey:@"action"];
|
||||
}
|
||||
|
||||
+ (void)_addToParameters:(NSMutableDictionary *)parameters
|
||||
forSharePhotoContent:(FBSDKSharePhotoContent *)photoContent
|
||||
{
|
||||
[FBSDKInternalUtility dictionary:parameters
|
||||
setObject:[photoContent.photos valueForKeyPath:@"image"]
|
||||
forKey:@"photos"];
|
||||
}
|
||||
|
||||
+ (void)_addToParameters:(NSMutableDictionary *)parameters
|
||||
forShareLinkContent:(FBSDKShareLinkContent *)linkContent
|
||||
{
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL forKey:@"link"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentTitle forKey:@"name"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentDescription forKey:@"description"];
|
||||
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.imageURL forKey:@"picture"];
|
||||
}
|
||||
|
||||
+ (void)_addToParameters:(NSMutableDictionary *)parameters
|
||||
forShareVideoContent:(FBSDKShareVideoContent *)videoContent
|
||||
{
|
||||
NSMutableDictionary *videoParameters = [[NSMutableDictionary alloc] init];
|
||||
FBSDKShareVideo *video = videoContent.video;
|
||||
NSURL *videoURL = video.videoURL;
|
||||
if (videoURL) {
|
||||
videoParameters[@"assetURL"] = videoURL;
|
||||
}
|
||||
[FBSDKInternalUtility dictionary:videoParameters
|
||||
setObject:[self _convertPhoto:videoContent.previewPhoto]
|
||||
forKey:@"previewPhoto"];
|
||||
parameters[@"video"] = videoParameters;
|
||||
}
|
||||
|
||||
+ (id)_convertObject:(id)object
|
||||
{
|
||||
if ([object isKindOfClass:[FBSDKShareOpenGraphValueContainer class]]) {
|
||||
object = [self _convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object requireNamespace:YES];
|
||||
} else if ([object isKindOfClass:[FBSDKSharePhoto class]]) {
|
||||
object = [self _convertPhoto:(FBSDKSharePhoto *)object];
|
||||
} else if ([object isKindOfClass:[NSArray class]]) {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||
for (id item in (NSArray *)object) {
|
||||
[FBSDKInternalUtility array:array addObject:[self _convertObject:item]];
|
||||
}
|
||||
object = array;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)_convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)container
|
||||
requireNamespace:(BOOL)requireNamespace
|
||||
{
|
||||
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
||||
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
|
||||
[container enumerateKeysAndObjectsUsingBlock:^(NSString *key, id object, BOOL *stop) {
|
||||
// if we have an FBSDKShareOpenGraphObject and a type, then we are creating a new object instance; set the flag
|
||||
if ([key isEqualToString:@"og:type"] && [container isKindOfClass:[FBSDKShareOpenGraphObject class]]) {
|
||||
dictionary[@"fbsdk:create_object"] = @YES;
|
||||
dictionary[key] = object;
|
||||
}
|
||||
id value = [self _convertObject:object];
|
||||
if (value) {
|
||||
NSString *namespace;
|
||||
key = [self getOpenGraphNameAndNamespaceFromFullName:key namespace:&namespace];
|
||||
|
||||
if (requireNamespace) {
|
||||
if ([namespace isEqualToString:@"og"]) {
|
||||
dictionary[key] = value;
|
||||
} else {
|
||||
data[key] = value;
|
||||
}
|
||||
} else {
|
||||
dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
}];
|
||||
if ([data count]) {
|
||||
dictionary[@"data"] = data;
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
+ (NSString *)getOpenGraphNameAndNamespaceFromFullName:(NSString *)fullName namespace:(NSString **)namespace {
|
||||
if (namespace) {
|
||||
*namespace = nil;
|
||||
}
|
||||
|
||||
if ([fullName isEqualToString:@"fb:explicitly_shared"]) {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
NSUInteger index = [fullName rangeOfString:@":"].location;
|
||||
if ((index != NSNotFound) && (fullName.length > index + 1)) {
|
||||
if (namespace) {
|
||||
*namespace = [fullName substringToIndex:index];
|
||||
}
|
||||
|
||||
return [fullName substringFromIndex:index + 1];
|
||||
}
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)_convertPhoto:(FBSDKSharePhoto *)photo
|
||||
{
|
||||
if (!photo) {
|
||||
return nil;
|
||||
}
|
||||
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
|
||||
dictionary[@"user_generated"] = @(photo.userGenerated);
|
||||
[FBSDKInternalUtility dictionary:dictionary setObject:photo.caption forKey:@"caption"];
|
||||
|
||||
[FBSDKInternalUtility dictionary:dictionary setObject:photo.image ?: photo.imageURL.absoluteString forKey:@"url"];
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
+ (BOOL)_isOpenGraphValue:(id)value
|
||||
{
|
||||
return ((value == nil) ||
|
||||
[value isKindOfClass:[NSNull class]] ||
|
||||
[value isKindOfClass:[NSNumber class]] ||
|
||||
[value isKindOfClass:[NSString class]] ||
|
||||
[value isKindOfClass:[NSURL class]] ||
|
||||
[value isKindOfClass:[FBSDKSharePhoto class]] ||
|
||||
[value isKindOfClass:[FBSDKShareOpenGraphObject class]]);
|
||||
}
|
||||
|
||||
+ (void)_testObject:(id)object containsMedia:(BOOL *)containsMediaRef containsPhotos:(BOOL *)containsPhotosRef
|
||||
{
|
||||
BOOL containsMedia = NO;
|
||||
BOOL containsPhotos = NO;
|
||||
if ([object isKindOfClass:[FBSDKSharePhoto class]]) {
|
||||
containsMedia = (((FBSDKSharePhoto *)object).image != nil);
|
||||
containsPhotos = YES;
|
||||
} else if ([object isKindOfClass:[FBSDKShareOpenGraphValueContainer class]]) {
|
||||
[self _testOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object
|
||||
containsMedia:&containsMedia
|
||||
containsPhotos:&containsPhotos];
|
||||
} else if ([object isKindOfClass:[NSArray class]]) {
|
||||
for (id item in (NSArray *)object) {
|
||||
BOOL itemContainsMedia = NO;
|
||||
BOOL itemContainsPhotos = NO;
|
||||
[self _testObject:item containsMedia:&itemContainsMedia containsPhotos:&itemContainsPhotos];
|
||||
containsMedia |= itemContainsMedia;
|
||||
containsPhotos |= itemContainsPhotos;
|
||||
if (containsMedia && containsPhotos) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (containsMediaRef != NULL) {
|
||||
*containsMediaRef = containsMedia;
|
||||
}
|
||||
if (containsPhotosRef != NULL) {
|
||||
*containsPhotosRef = containsPhotos;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)_testOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)container
|
||||
containsMedia:(BOOL *)containsMediaRef
|
||||
containsPhotos:(BOOL *)containsPhotosRef
|
||||
{
|
||||
__block BOOL containsMedia = NO;
|
||||
__block BOOL containsPhotos = NO;
|
||||
[container enumerateKeysAndObjectsUsingBlock:^(NSString *key, id object, BOOL *stop) {
|
||||
BOOL itemContainsMedia = NO;
|
||||
BOOL itemContainsPhotos = NO;
|
||||
[self _testObject:object containsMedia:&itemContainsMedia containsPhotos:&itemContainsPhotos];
|
||||
containsMedia |= itemContainsMedia;
|
||||
containsPhotos |= itemContainsPhotos;
|
||||
if (containsMedia && containsPhotos) {
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
if (containsMediaRef != NULL) {
|
||||
*containsMediaRef = containsMedia;
|
||||
}
|
||||
if (containsPhotosRef != NULL) {
|
||||
*containsPhotosRef = containsPhotos;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)_validateArray:(NSArray *)array
|
||||
minCount:(NSUInteger)minCount
|
||||
maxCount:(NSUInteger)maxCount
|
||||
name:(NSString *)name
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
NSUInteger count = [array count];
|
||||
if ((count < minCount) || (count > maxCount)) {
|
||||
if (errorRef != NULL) {
|
||||
NSString *message = [[NSString alloc] initWithFormat:@"%@ must have %lu to %lu values",
|
||||
name,
|
||||
(unsigned long)minCount,
|
||||
(unsigned long)maxCount];
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:array message:message];
|
||||
}
|
||||
return NO;
|
||||
} else {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)_validateFileURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (!URL) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
if (!URL.isFileURL) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:URL message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
// ensure that the file exists. per the latest spec for NSFileManager, we should not be checking for file existance,
|
||||
// so they have removed that option for URLs and discourage it for paths, so we just construct a mapped NSData.
|
||||
NSError *fileError;
|
||||
if (![[NSData alloc] initWithContentsOfURL:URL
|
||||
options:NSDataReadingMapped
|
||||
error:&fileError]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:name
|
||||
value:URL
|
||||
message:@"Error reading file"
|
||||
underlyingError:fileError];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)_validateNetworkURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (!URL || [FBSDKInternalUtility isBrowserURL:URL]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
} else {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:URL message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)_validateRequiredValue:(id)value name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
if (!value ||
|
||||
([value isKindOfClass:[NSString class]] && ![(NSString *)value length]) ||
|
||||
([value isKindOfClass:[NSArray class]] && ![(NSArray *)value count]) ||
|
||||
([value isKindOfClass:[NSDictionary class]] && ![(NSDictionary *)value count])) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:name message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)_validateArgumentWithName:(NSString *)argumentName
|
||||
value:(NSUInteger)value
|
||||
isIn:(NSArray *)possibleValues
|
||||
error:(NSError *__autoreleasing *)errorRef
|
||||
{
|
||||
for (NSNumber *possibleValue in possibleValues) {
|
||||
if (value == [possibleValue unsignedIntegerValue]) {
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
if (errorRef != NULL) {
|
||||
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:argumentName value:@(value) message:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKCoreKit.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareVideo.h>
|
||||
#import <FBSDKShareKit/FBSDKSharing.h>
|
||||
|
||||
@protocol FBSDKVideoUploaderDelegate;
|
||||
|
||||
/*!
|
||||
@abstract A utility class for uploading through the chunk upload graph API. Using this class requires an access token in
|
||||
`[FBSDKAccessToken currentAccessToken]` that has been granted the "publish_actions" permission.
|
||||
@discussion see https://developers.facebook.com/docs/graph-api/video-uploads
|
||||
*/
|
||||
@interface FBSDKVideoUploader : NSObject
|
||||
|
||||
/*!
|
||||
@abstract Initialize videoUploader
|
||||
@param videoName The file name of the video to be uploaded
|
||||
@param videoSize The size of the video to be uploaded
|
||||
@param parameters Optional parameters for video uploads. See Graph API documentation for the full list of parameters https://developers.facebook.com/docs/graph-api/reference/video
|
||||
@param delegate Receiver's delegate
|
||||
*/
|
||||
- (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)videoSize parameters:(NSDictionary *)parameters delegate:(id<FBSDKVideoUploaderDelegate>)delegate
|
||||
NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
|
||||
/*!
|
||||
@abstract The video to be uploaded.
|
||||
*/
|
||||
@property (readonly, copy, nonatomic) FBSDKShareVideo *video;
|
||||
|
||||
/*!
|
||||
@abstract Optional parameters for video uploads. See Graph API documentation for the full list of parameters https://developers.facebook.com/docs/graph-api/reference/video
|
||||
*/
|
||||
@property (copy, nonatomic) NSDictionary *parameters;
|
||||
|
||||
/*!
|
||||
@abstract The graph node to which video should be uploaded
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *graphNode;
|
||||
|
||||
/*!
|
||||
@abstract Receiver's delegate
|
||||
*/
|
||||
@property (weak, nonatomic) id<FBSDKVideoUploaderDelegate> delegate;
|
||||
|
||||
/*!
|
||||
@abstract Start upload process
|
||||
*/
|
||||
//TODO #6229672 add cancel and/or pause
|
||||
- (void)start;
|
||||
|
||||
@end
|
||||
|
||||
/*!
|
||||
@abstract A delegate for `FBSDKVideoUploader`.
|
||||
@discussion The delegate passes video chunk to `FBSDKVideoUploader` object in `NSData` format and is notified with the results of the uploader.
|
||||
*/
|
||||
@protocol FBSDKVideoUploaderDelegate <NSObject>
|
||||
|
||||
/*!
|
||||
@abstract get chunk of the video to be uploaded in 'NSData' format
|
||||
@param videoUploader The `FBSDKVideoUploader` object which is performing the upload process
|
||||
@param startOffset The start offset of video chunk to be uploaded
|
||||
@param endOffset The end offset of video chunk being to be uploaded
|
||||
*/
|
||||
- (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader startOffset:(NSUInteger) startOffset endOffset:(NSUInteger) endOffset;
|
||||
|
||||
/*!
|
||||
@abstract Notify the delegate that upload process success.
|
||||
@param videoUploader The `FBSDKVideoUploader` object which is performing the upload process
|
||||
@param results The result from successful upload
|
||||
*/
|
||||
- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didCompleteWithResults:(NSDictionary *)results;
|
||||
|
||||
/*!
|
||||
@abstract Notify the delegate that upload process fails.
|
||||
@param videoUploader The `FBSDKVideoUploader` object which is performing the upload process
|
||||
@param error The error object from unsuccessful upload
|
||||
*/
|
||||
- (void)videoUploader:(FBSDKVideoUploader *)videoUploader didFailWithError:(NSError *)error;
|
||||
|
||||
@end
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
//
|
||||
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
// copy, modify, and distribute this software in source code or binary form for use
|
||||
// in connection with the web services and APIs provided by Facebook.
|
||||
//
|
||||
// As with any software that integrates with the Facebook platform, your use of
|
||||
// this software is subject to the Facebook Developer Principles and Policies
|
||||
// [http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
// included in all copies or substantial portions of the software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#import "FBSDKVideoUploader.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FBSDKCoreKit/FBSDKGraphRequestDataAttachment.h>
|
||||
|
||||
#import <FBSDKShareKit/FBSDKShareConstants.h>
|
||||
|
||||
#import "FBSDKShareDefines.h"
|
||||
#import "FBSDKShareError.h"
|
||||
|
||||
static NSString *const FBSDKVideoUploaderDefaultGraphNode = @"me";
|
||||
static NSString *const FBSDKVideoUploaderEdge = @"videos";
|
||||
|
||||
@implementation FBSDKVideoUploader
|
||||
{
|
||||
NSNumber *_videoID;
|
||||
NSNumber *_uploadSessionID;
|
||||
NSNumberFormatter *_numberFormatter;
|
||||
NSString *_graphPath;
|
||||
NSString *_videoName;
|
||||
NSUInteger _videoSize;
|
||||
}
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#pragma Public Method
|
||||
- (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)videoSize parameters:(NSDictionary *)parameters delegate:(id<FBSDKVideoUploaderDelegate>)delegate
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_parameters = [parameters copy];
|
||||
_delegate = delegate;
|
||||
_graphNode = FBSDKVideoUploaderDefaultGraphNode;
|
||||
_videoName = videoName;
|
||||
_videoSize = videoSize;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)start
|
||||
{
|
||||
_graphPath = [self _graphPathWithSuffix:FBSDKVideoUploaderEdge, nil];
|
||||
[self _postStartRequest];
|
||||
}
|
||||
|
||||
#pragma Helper Method
|
||||
|
||||
- (void)_postStartRequest
|
||||
{
|
||||
FBSDKGraphRequestHandler startRequestCompletionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error)
|
||||
{
|
||||
if (error) {
|
||||
[self.delegate videoUploader:self didFailWithError:error];
|
||||
return;
|
||||
} else {
|
||||
result = [FBSDKTypeUtility dictionaryValue:result];
|
||||
NSNumber *uploadSessionID = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID]];
|
||||
NSNumber *videoID = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_ID]];
|
||||
NSDictionary *offsetDictionary = [self _extractOffsetsFromResultDictionary:result];
|
||||
if (uploadSessionID == nil || videoID == nil) {
|
||||
[self.delegate videoUploader:self didFailWithError:[
|
||||
FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode
|
||||
message:@"Failed to get valid upload_session_id or video_id."]];
|
||||
return;
|
||||
} else if (offsetDictionary == nil) {
|
||||
return;
|
||||
}
|
||||
_uploadSessionID = uploadSessionID;
|
||||
_videoID = videoID;
|
||||
[self _startTransferRequestWithOffsetDictionary:offsetDictionary];
|
||||
}
|
||||
};
|
||||
if (_videoSize == 0) {
|
||||
[self.delegate videoUploader:self didFailWithError:[
|
||||
FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode
|
||||
message:[NSString stringWithFormat:@"Invalid video size: %lu", (unsigned long)_videoSize]]];
|
||||
return;
|
||||
}
|
||||
[[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath
|
||||
parameters:@{
|
||||
FBSDK_SHARE_VIDEO_UPLOAD_PHASE: FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START,
|
||||
FBSDK_SHARE_VIDEO_SIZE: [NSString stringWithFormat:@"%tu", _videoSize],
|
||||
}
|
||||
HTTPMethod:@"POST"] startWithCompletionHandler:startRequestCompletionHandler];
|
||||
}
|
||||
|
||||
- (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictionary
|
||||
{
|
||||
dispatch_queue_t dataQueue;
|
||||
NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 };
|
||||
if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) {
|
||||
dataQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
|
||||
} else {
|
||||
dataQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
|
||||
}
|
||||
NSUInteger startOffset = [offsetDictionary[FBSDK_SHARE_VIDEO_START_OFFSET] unsignedIntegerValue];
|
||||
NSUInteger endOffset = [offsetDictionary[FBSDK_SHARE_VIDEO_END_OFFSET] unsignedIntegerValue];
|
||||
if (startOffset == endOffset) {
|
||||
[self _postFinishRequest];
|
||||
return;
|
||||
} else {
|
||||
dispatch_async(dataQueue, ^{
|
||||
size_t chunkSize = (unsigned long)(endOffset - startOffset);
|
||||
NSData *data = [self.delegate videoChunkDataForVideoUploader:self startOffset:startOffset endOffset:endOffset];
|
||||
if (data == nil || data.length != chunkSize) {
|
||||
[self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message:
|
||||
[NSString stringWithFormat:@"Fail to get video chunk with start offset: %lu, end offset : %lu.", (unsigned long)startOffset, (unsigned long)endOffset]]];
|
||||
return;
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
FBSDKGraphRequestDataAttachment *dataAttachment = [[FBSDKGraphRequestDataAttachment alloc] initWithData:data
|
||||
filename:_videoName
|
||||
contentType:nil];
|
||||
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath
|
||||
parameters:@{
|
||||
FBSDK_SHARE_VIDEO_UPLOAD_PHASE: FBSDK_SHARE_VIDEO_UPLOAD_PHASE_TRANSFER,
|
||||
FBSDK_SHARE_VIDEO_START_OFFSET: offsetDictionary[FBSDK_SHARE_VIDEO_START_OFFSET],
|
||||
FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID: _uploadSessionID,
|
||||
FBSDK_SHARE_VIDEO_FILE_CHUNK: dataAttachment,
|
||||
}
|
||||
HTTPMethod:@"POST"];
|
||||
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *innerError) {
|
||||
if (innerError) {
|
||||
[self.delegate videoUploader:self didFailWithError:innerError];
|
||||
return;
|
||||
}
|
||||
NSDictionary *innerOffsetDictionary = [self _extractOffsetsFromResultDictionary:result];
|
||||
if (innerOffsetDictionary == nil) {
|
||||
return;
|
||||
}
|
||||
[self _startTransferRequestWithOffsetDictionary:innerOffsetDictionary];
|
||||
}];
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_postFinishRequest
|
||||
{
|
||||
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
||||
parameters[FBSDK_SHARE_VIDEO_UPLOAD_PHASE] = FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH;
|
||||
parameters[FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID] = _uploadSessionID;
|
||||
[parameters addEntriesFromDictionary:self.parameters];
|
||||
[[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath
|
||||
parameters:parameters
|
||||
HTTPMethod:@"POST"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
|
||||
if (error) {
|
||||
[self.delegate videoUploader:self didFailWithError:error];
|
||||
} else {
|
||||
result = [FBSDKTypeUtility dictionaryValue:result];
|
||||
if (result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] == nil) {
|
||||
[self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode
|
||||
message:@"Failed to finish uploading."]];
|
||||
return;
|
||||
}
|
||||
NSMutableDictionary *shareResult = [[NSMutableDictionary alloc] init];
|
||||
shareResult[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] = result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS];
|
||||
shareResult[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY] = FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST;
|
||||
shareResult[FBSDK_SHARE_VIDEO_ID] = _videoID;
|
||||
[self.delegate videoUploader:self didCompleteWithResults:shareResult];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSDictionary *)_extractOffsetsFromResultDictionary:(id)result
|
||||
{
|
||||
result = [FBSDKTypeUtility dictionaryValue:result];
|
||||
NSNumber *startNum = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_START_OFFSET]];
|
||||
NSNumber *endNum = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_END_OFFSET]];
|
||||
if (startNum == nil || endNum == nil) {
|
||||
[self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode
|
||||
message:@"Fail to get valid start_offset or end_offset."]];
|
||||
return nil;
|
||||
}
|
||||
if ([startNum compare:endNum] == NSOrderedDescending) {
|
||||
[self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode
|
||||
message:@"Invalid offset: start_offset is greater than end_offset."]];
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init];
|
||||
shareResults[FBSDK_SHARE_VIDEO_START_OFFSET] = startNum;
|
||||
shareResults[FBSDK_SHARE_VIDEO_END_OFFSET] = endNum;
|
||||
return shareResults;
|
||||
}
|
||||
|
||||
- (NSNumberFormatter *)numberFormatter
|
||||
{
|
||||
if (!_numberFormatter) {
|
||||
_numberFormatter = [[NSNumberFormatter alloc] init];
|
||||
_numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
|
||||
}
|
||||
return _numberFormatter;
|
||||
}
|
||||
|
||||
- (NSString *)_graphPathWithSuffix:(NSString *)suffix, ... NS_REQUIRES_NIL_TERMINATION
|
||||
{
|
||||
NSMutableString *graphPath = [[NSMutableString alloc] initWithString:self.graphNode];
|
||||
va_list args;
|
||||
va_start(args, suffix);
|
||||
for (NSString *arg = suffix; arg != nil; arg = va_arg(args, NSString *)) {
|
||||
[graphPath appendFormat:@"/%@", arg];
|
||||
}
|
||||
va_end(args);
|
||||
return graphPath;
|
||||
}
|
||||
|
||||
@end
|
||||
Generated
+17
@@ -0,0 +1,17 @@
|
||||
Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
||||
|
||||
You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
||||
copy, modify, and distribute this software in source code or binary form for use
|
||||
in connection with the web services and APIs provided by Facebook.
|
||||
|
||||
As with any software that integrates with the Facebook platform, your use of
|
||||
this software is subject to the Facebook Developer Principles and Policies
|
||||
[http://developers.facebook.com/policy/]. This copyright notice shall be
|
||||
included in all copies or substantial portions of the software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Generated
+46
@@ -0,0 +1,46 @@
|
||||
Facebook SDK for iOS
|
||||
====================
|
||||
|
||||
This open-source library allows you to integrate Facebook into your iOS app.
|
||||
|
||||
Learn more about the provided samples, documentation, integrating the SDK into your app, accessing source code, and more at https://developers.facebook.com/docs/ios
|
||||
|
||||
NOTE: By default, the Facebook SDK for iOS is installed in ~/Documents/FacebookSDK
|
||||
|
||||
TRY IT OUT
|
||||
----------
|
||||
1. Download the SDK at https://developers.facebook.com/docs/ios or via CocoaPods by adding the 'FBSDKCoreKit', 'FBSDKLoginKit', and 'FBSDKShareKit' pods.
|
||||
2. Test your install: build and run the project at ~/Documents/FacebookSDK/Samples/Scrumptious/Scrumptious.xcodeproj
|
||||
3. Check-out the tutorials available online at: https://developers.facebook.com/docs/ios/getting-started
|
||||
4. Start coding! Visit https://developers.facebook.com/docs/ios for tutorials and reference documentation.
|
||||
|
||||
FEATURES
|
||||
--------
|
||||
* Login - https://developers.facebook.com/docs/facebook-login
|
||||
* Sharing - https://developers.facebook.com/docs/sharing
|
||||
* App Links - https://developers.facebook.com/docs/applinks
|
||||
* Graph API - https://developers.facebook.com/docs/ios/graph
|
||||
* Analytics for Apps - https://developers.facebook.com/docs/analytics
|
||||
|
||||
GIVE FEEDBACK
|
||||
-------------
|
||||
Please report bugs or issues to https://developers.facebook.com/bugs/
|
||||
|
||||
You can also join the Facebook Developers Group on Facebook (https://www.facebook.com/groups/fbdevelopers/) or ask questions on Stack Overflow (http://facebook.stackoverflow.com)
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
See the LICENSE file.
|
||||
|
||||
DEVELOPER TERMS
|
||||
---------------
|
||||
|
||||
- By enabling Facebook integrations, including through this SDK, you can share information with Facebook, including information about people’s use of your app. Facebook will use information received in accordance with our Data Use Policy [https://www.facebook.com/about/privacy/], including to provide you with insights about the effectiveness of your ads and the use of your app. These integrations also enable us and our partners to serve ads on and off Facebook.
|
||||
|
||||
- You may limit your sharing of information with us by updating the Insights control in the developer tool [https://developers.facebook.com/apps/{app_id}/settings/advanced].
|
||||
|
||||
- If you use a Facebook integration, including to share information with us, you agree and confirm that you have provided appropriate and sufficiently prominent notice to and obtained the appropriate consent from your users regarding such collection, use, and disclosure (including, at a minimum, through your privacy policy). You further agree that you will not share information with us about children under the age of 13.
|
||||
|
||||
- You agree to comply with all applicable laws and regulations and also agree to our Terms <https://www.facebook.com/policies/>, including our Platform Policies <https://developers.facebook.com/policy/>.and Advertising Guidelines, as applicable <https://www.facebook.com/ad_guidelines.php>.
|
||||
|
||||
By using the Facebook SDK for iOS you agree to these terms.
|
||||
Reference in new issue
Block a user