- add - (BOOL) removeObjectsWithClass:(Class _Nonnull) class

- fix - (id _Nonnull) saveLocally:(id _Nonnull) object
- upgrade libraries
This commit is contained in:
giuseppenuc committed 2018-10-10 01:16:12 +02:00
1 parent 874707e958
commit 99e06e67db
239 files changed
+13154 -6570

No files matched your search

@@ -24,45 +24,45 @@
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
__attribute__ ((deprecated))
@interface FBSDKAppGroupAddDialog : NSObject
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
+ (instancetype)showWithContent:(FBSDKAppGroupContent *)content
delegate:(id<FBSDKAppGroupAddDialogDelegate>)delegate __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
@property (nonatomic, weak) id<FBSDKAppGroupAddDialogDelegate> delegate __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
@property (nonatomic, copy) FBSDKAppGroupContent *content __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (BOOL)canShow __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (BOOL)show __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef __attribute__ ((deprecated));
@@ -70,26 +70,26 @@ __attribute__ ((deprecated))
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
__attribute__ ((deprecated))
@protocol FBSDKAppGroupAddDialogDelegate <NSObject>
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (void)appGroupAddDialog:(FBSDKAppGroupAddDialog *)appGroupAddDialog didCompleteWithResults:(NSDictionary *)results __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (void)appGroupAddDialog:(FBSDKAppGroupAddDialog *)appGroupAddDialog didFailWithError:(NSError *)error __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (void)appGroupAddDialogDidCancel:(FBSDKAppGroupAddDialog *)appGroupAddDialog __attribute__ ((deprecated));
@@ -60,8 +60,8 @@ FBSDK_EXTERN NSString *NSStringFromFBSDKAppGroupPrivacy(FBSDKAppGroupPrivacy pri
/**
Compares the receiver to another app group content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@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;
@@ -22,43 +22,43 @@
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
__attribute__ ((deprecated))
@interface FBSDKAppGroupJoinDialog : NSObject
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
+ (instancetype)showWithGroupID:(NSString *)groupID
delegate:(id<FBSDKAppGroupJoinDialogDelegate>)delegate __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */
@property (nonatomic, weak) id<FBSDKAppGroupJoinDialogDelegate> delegate __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */
@property (nonatomic, copy) NSString *groupID __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (BOOL)canShow __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (BOOL)show __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef __attribute__ ((deprecated));
@@ -66,26 +66,26 @@ __attribute__ ((deprecated))
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
__attribute__ ((deprecated))
@protocol FBSDKAppGroupJoinDialogDelegate <NSObject>
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (void)appGroupJoinDialog:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog didCompleteWithResults:(NSDictionary *)results __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (void)appGroupJoinDialog:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog didFailWithError:(NSError *)error __attribute__ ((deprecated));
/**
- Warning:App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
@warning App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information.
*/
- (void)appGroupJoinDialogDidCancel:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog __attribute__ ((deprecated));
@@ -19,6 +19,7 @@
#import <Foundation/Foundation.h>
#import <FBSDKCoreKit/FBSDKCopying.h>
#import <FBSDKShareKit/FBSDKSharingValidation.h>
/**
NS_ENUM(NSUInteger, FBSDKAppInviteDestination)
@@ -35,7 +36,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAppInviteDestination)
/**
A model for app invite.
*/
@interface FBSDKAppInviteContent : NSObject <FBSDKCopying, NSSecureCoding>
@interface FBSDKAppInviteContent : NSObject <FBSDKCopying, FBSDKSharingValidation, NSSecureCoding>
/**
A URL to a preview image that will be displayed with the app invite
@@ -55,7 +56,7 @@ typedef NS_ENUM(NSUInteger, FBSDKAppInviteDestination)
/**
- Warning:Use `appInvitePreviewImageURL` instead.
@warning Use `appInvitePreviewImageURL` instead.
*/
@property (nonatomic, copy) NSURL *previewImageURL __attribute__ ((deprecated("use appInvitePreviewImageURL instead")));
@@ -87,8 +88,8 @@ typedef NS_ENUM(NSUInteger, FBSDKAppInviteDestination)
/**
Compares the receiver to another app invite content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@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;
@@ -19,6 +19,7 @@
#import "FBSDKAppInviteContent.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareUtility.h"
#define FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY @"appLinkURL"
#define FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY @"previewImage"
@@ -39,6 +40,60 @@
self.appInvitePreviewImageURL = previewImageURL;
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
return ([FBSDKShareUtility validateRequiredValue:_appLinkURL name:@"appLinkURL" error:errorRef] &&
[FBSDKShareUtility validateNetworkURL:_appLinkURL name:@"appLinkURL" error:errorRef] &&
[FBSDKShareUtility validateNetworkURL:_appInvitePreviewImageURL name:@"appInvitePreviewImageURL" error:errorRef] &&
[self _validatePromoCodeWithError:errorRef]);
}
- (BOOL)_validatePromoCodeWithError:(NSError *__autoreleasing *)errorRef
{
if ([_promotionText length] > 0 || [_promotionCode length] > 0) {
NSMutableCharacterSet *alphanumericWithSpaces = [NSMutableCharacterSet alphanumericCharacterSet];
[alphanumericWithSpaces formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
// Check for validity of promo text and promo code.
if (!([_promotionText length] > 0 && [_promotionText length] <= 80)) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionText" value:_promotionText message:@"Invalid value for promotionText, promotionText has to be between 1 and 80 characters long."];
}
return NO;
}
if (!([_promotionCode length] <= 10)) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionCode" value:_promotionCode message:@"Invalid value for promotionCode, promotionCode has to be between 0 and 10 characters long and is required when promoCode is set."];
}
return NO;
}
if ([_promotionText rangeOfCharacterFromSet:[alphanumericWithSpaces invertedSet]].location != NSNotFound) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionText" value:_promotionText message:@"Invalid value for promotionText, promotionText can contain only alphanumeric characters and spaces."];
}
return NO;
}
if ([_promotionCode length] > 0 && [_promotionCode rangeOfCharacterFromSet:[alphanumericWithSpaces invertedSet]].location != NSNotFound) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionCode" value:_promotionCode message:@"Invalid value for promotionCode, promotionCode can contain only alphanumeric characters and spaces."];
}
return NO;
}
}
if (errorRef != NULL) {
*errorRef = nil;
}
return YES;
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -30,10 +30,10 @@
/**
Convenience method to show a FBSDKAppInviteDialog
- Parameter viewController: A UIViewController to present the dialog from.
- Parameter content: The content for the app invite.
- Parameter delegate: The receiver's delegate.
- Warning: This method is deprecated.
@param viewController A UIViewController to present the dialog from.
@param content The content for the app invite.
@param delegate The receiver's delegate.
@warning This method is deprecated.
*/
+ (instancetype)showFromViewController:(UIViewController *)viewController
withContent:(FBSDKAppInviteContent *)content
@@ -43,7 +43,7 @@ __attribute__ ((deprecated("App Invites no longer supported")));
/**
- Warning:use showFromViewController:withContent:delegate: instead
@warning use showFromViewController:withContent:delegate: instead
*/
+ (instancetype)showWithContent:(FBSDKAppInviteContent *)content delegate:(id<FBSDKAppInviteDialogDelegate>)delegate
__attribute__ ((deprecated("use showFromViewController:withContent:delegate: instead")));
@@ -72,21 +72,21 @@ __attribute__ ((deprecated("use showFromViewController:withContent:delegate: ins
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:
- Returns: YES if the receiver can show the dialog, otherwise NO.
@see validateWithError:
@return YES if the receiver can show the dialog, otherwise NO.
*/
- (BOOL)canShow;
/**
Begins the app invite from the receiver.
- Returns: YES if the receiver was able to show the dialog, otherwise NO.
@return YES if the receiver was able to show the dialog, otherwise NO.
*/
- (BOOL)show;
/**
Validates the content on the receiver.
- Parameter errorRef: If an error occurs, upon return contains an NSError object that describes the problem.
- Returns: YES if the content is valid, otherwise NO.
@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;
@@ -103,15 +103,15 @@ __attribute__ ((deprecated("use showFromViewController:withContent:delegate: ins
/**
Sent to the delegate when the app invite completes without error.
- Parameter appInviteDialog: The FBSDKAppInviteDialog that completed.
- Parameter results: The results from the dialog. This may be nil or empty.
@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;
/**
Sent to the delegate when the app invite encounters an error.
- Parameter appInviteDialog: The FBSDKAppInviteDialog that completed.
- Parameter error: The error.
@param appInviteDialog The FBSDKAppInviteDialog that completed.
@param error The error.
*/
- (void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didFailWithError:(NSError *)error;
@@ -68,7 +68,16 @@
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
{
return [FBSDKShareUtility validateAppInviteContent:self.content error:errorRef];
if (![FBSDKShareUtility validateRequiredValue:self.content name:@"content" error:errorRef]) {
return NO;
}
if ([self.content respondsToSelector:@selector(validateWithError:)]) {
return [self.content validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef];
}
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"content" value:self.content message:nil];
}
return NO;
}
@end
@@ -28,29 +28,29 @@
/**
Sets a string argument in the container.
- Parameter string: The argument
- Parameter key: The key for the argument
@param string The argument
@param key The key for the argument
*/
- (void)setString:(NSString *)string forKey:(NSString *)key;
/**
Gets a string argument from the container.
- Parameter key: The key for the argument
- Returns: The string value or nil
@param key The key for the argument
@return The string value or nil
*/
- (NSString *)stringForKey:(NSString *)key;
/**
Sets a string array argument in the container.
- Parameter array: The array argument
- Parameter key: The key for the argument
@param array The array argument
@param key The key for the argument
*/
- (void)setArray:(NSArray<NSString *> *)array forKey:(NSString *)key;
/**
Gets an array argument from the container.
- Parameter key: The key for the argument
- Returns: The array argument
@param key The key for the argument
@return The array argument
*/
- (NSArray *)arrayForKey:(NSString *)key;
@@ -28,15 +28,15 @@
/**
Sets the image for a texture key.
- Parameter image: The UIImage for the texture
- Parameter name: The key for the texture
@param image The UIImage for the texture
@param key The key for the texture
*/
- (void)setImage:(UIImage *)image forKey:(NSString *)key;
/**
Gets the image for a texture key.
- Parameter name: The key for the texture
- Returns: The texture UIImage or nil
@param key The key for the texture
@return The texture UIImage or nil
*/
- (UIImage *)imageForKey:(NSString *)key;
@@ -19,6 +19,7 @@
#import <Foundation/Foundation.h>
#import <FBSDKCoreKit/FBSDKCopying.h>
#import <FBSDKShareKit/FBSDKSharingValidation.h>
/**
NS_ENUM(NSUInteger, FBSDKGameRequestActionType)
@@ -53,7 +54,7 @@ typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilter)
/**
A model for a game request.
*/
@interface FBSDKGameRequestContent : NSObject <FBSDKCopying, NSSecureCoding>
@interface FBSDKGameRequestContent : NSObject <FBSDKCopying, FBSDKSharingValidation, NSSecureCoding>
/**
Used when defining additional context about the nature of the request.
@@ -67,8 +68,8 @@ typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilter)
/**
Compares the receiver to another game request content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@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;
@@ -121,7 +122,7 @@ typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilter)
/**
- Warning:Use `recipientSuggestions` instead.
@warning Use `recipientSuggestions` instead.
*/
@property (nonatomic, copy) NSArray *suggestions __attribute__ ((deprecated("use recipientSuggestions instead")));
@@ -132,7 +133,7 @@ typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilter)
/**
- Warning:Use `recipients` instead.
@warning Use `recipients` instead.
*/
@property (nonatomic, copy) NSArray *to __attribute__ ((deprecated("use recipients instead")));
@@ -19,6 +19,7 @@
#import "FBSDKGameRequestContent.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareError.h"
#import "FBSDKShareUtility.h"
#define FBSDK_APP_REQUEST_CONTENT_TO_KEY @"to"
@@ -70,6 +71,76 @@
self.recipients = to;
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
if (![FBSDKShareUtility validateRequiredValue:_message name:@"message" error:errorRef]) {
return NO;
}
BOOL mustHaveobjectID = _actionType == FBSDKGameRequestActionTypeSend
|| _actionType == FBSDKGameRequestActionTypeAskFor;
BOOL hasobjectID = [_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 = [_recipients count] > 0;
BOOL hasFilters = _filters != FBSDKGameRequestFilterNone;
BOOL hasSuggestions = [_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:_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:_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:_recipientSuggestions message:message];
}
return NO;
}
if ([_data length] > 255) {
if (errorRef != NULL) {
NSString *message = @"The data cannot be longer than 255 characters";
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"data" value:_data message:message];
}
return NO;
}
if (errorRef != NULL) {
*errorRef = nil;
}
return [FBSDKShareUtility validateArgumentWithName:@"actionType"
value:_actionType
isIn:@[@(FBSDKGameRequestActionTypeNone),
@(FBSDKGameRequestActionTypeSend),
@(FBSDKGameRequestActionTypeAskFor),
@(FBSDKGameRequestActionTypeTurn)]
error:errorRef]
&& [FBSDKShareUtility validateArgumentWithName:@"filters"
value:_filters
isIn:@[@(FBSDKGameRequestFilterNone),
@(FBSDKGameRequestFilterAppUsers),
@(FBSDKGameRequestFilterAppNonUsers)]
error:errorRef];
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -29,8 +29,8 @@
/**
Convenience method to build up a game request with content and a delegate.
- Parameter content: The content for the game request.
- Parameter delegate: The receiver's delegate.
@param content The content for the game request.
@param delegate The receiver's delegate.
*/
+ (instancetype)showWithContent:(FBSDKGameRequestContent *)content delegate:(id<FBSDKGameRequestDialogDelegate>)delegate;
@@ -56,21 +56,21 @@
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:
- Returns: YES if the receiver can share, otherwise NO.
@see validateWithError:
@return YES if the receiver can share, otherwise NO.
*/
- (BOOL)canShow;
/**
Begins the game request from the receiver.
- Returns: YES if the receiver was able to show the dialog, otherwise NO.
@return YES if the receiver was able to show the dialog, otherwise NO.
*/
- (BOOL)show;
/**
Validates the content on the receiver.
- Parameter errorRef: If an error occurs, upon return contains an NSError object that describes the problem.
- Returns: YES if the content is valid, otherwise NO.
@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;
@@ -87,21 +87,21 @@
/**
Sent to the delegate when the game request completes without error.
- Parameter gameRequestDialog: The FBSDKGameRequestDialog that completed.
- Parameter results: The results from the dialog. This may be nil or empty.
@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;
/**
Sent to the delegate when the game request encounters an error.
- Parameter gameRequestDialog: The FBSDKGameRequestDialog that completed.
- Parameter error: The error.
@param gameRequestDialog The FBSDKGameRequestDialog that completed.
@param error The error.
*/
- (void)gameRequestDialog:(FBSDKGameRequestDialog *)gameRequestDialog didFailWithError:(NSError *)error;
/**
Sent to the delegate when the game request dialog is cancelled.
- Parameter gameRequestDialog: The FBSDKGameRequestDialog that completed.
@param gameRequestDialog The FBSDKGameRequestDialog that completed.
*/
- (void)gameRequestDialogDidCancel:(FBSDKGameRequestDialog *)gameRequestDialog;
@@ -132,7 +132,16 @@ static FBSDKGameRequestFrictionlessRecipientCache *_recipientCache = nil;
- (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef
{
return [FBSDKShareUtility validateGameRequestContent:self.content error:errorRef];
if (![FBSDKShareUtility validateRequiredValue:self.content name:@"content" error:errorRef]) {
return NO;
}
if ([self.content respondsToSelector:@selector(validateWithOptions:error:)]) {
return [self.content validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef];
}
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"content" value:self.content message:nil];
}
return NO;
}
#pragma mark - FBSDKWebDialogDelegate
@@ -28,7 +28,7 @@
/**
Convenience method to build a new hashtag with a string identifier. Equivalent to setting the
`stringRepresentation` property.
- Parameter hashtagString: The hashtag string.
@param hashtagString The hashtag string.
*/
+ (instancetype)hashtagWithString:(NSString *)hashtagString;
@@ -38,7 +38,7 @@
You are responsible for making sure that `stringRepresentation` is a valid hashtag (a single '#' followed
by one or more word characters). Invalid hashtags are ignored when sharing content. You can check validity with the
`valid` property.
- Returns: The hashtag string.
@return The hashtag string.
*/
@property (nonatomic, readwrite, copy) NSString *stringRepresentation;
@@ -47,14 +47,14 @@
A valid hashtag matches the regular expression "#\w+": A single '#' followed by one or more
word characters.
- Returns: YES if the hashtag is valid, NO otherwise.
@return YES if the hashtag is valid, NO otherwise.
*/
@property (nonatomic, readonly, assign, getter=isValid) BOOL valid;
/**
Compares the receiver to another hashtag.
- Parameter hashtag: The other hashtag
- Returns: YES if the receiver is equal to the other hashtag; otherwise NO
@param hashtag The other hashtag
@return YES if the receiver is equal to the other hashtag; otherwise NO
*/
- (BOOL)isEqualToHashtag:(FBSDKHashtag *)hashtag;
@@ -103,7 +103,7 @@ __attribute__ ((deprecated))
The position for the auxiliary view for the receiver.
- See:FBSDKLikeControlAuxiliaryPosition
@see FBSDKLikeControlAuxiliaryPosition
*/
@property (nonatomic, assign) FBSDKLikeControlAuxiliaryPosition likeControlAuxiliaryPosition;
@@ -120,7 +120,7 @@ __attribute__ ((deprecated))
The style to use for the receiver.
- See:FBSDKLikeControlStyle
@see FBSDKLikeControlStyle
*/
@property (nonatomic, assign) FBSDKLikeControlStyle likeControlStyle;
@@ -590,17 +590,17 @@ static CGSize FBSDKLikeControlCalculateContentSize(FBSDKLikeControlLayout layout
view.frame = frame;
};
[UIView animateWithDuration:kFBLikeControlAnimationDuration animations:^{
hideView(_socialSentenceLabel);
hideView(self->_socialSentenceLabel);
} completion:^(BOOL finished) {
_socialSentenceLabel.text = likeActionController.socialSentence;
self->_socialSentenceLabel.text = likeActionController.socialSentence;
[self setNeedsLayout];
[self setNeedsUpdateConstraints];
[self invalidateIntrinsicContentSize];
[self layoutIfNeeded];
hideView(_socialSentenceLabel);
hideView(self->_socialSentenceLabel);
[UIView animateWithDuration:kFBLikeControlAnimationDuration animations:^{
_socialSentenceLabel.alpha = 1.0;
self->_socialSentenceLabel.alpha = 1.0;
[self setNeedsLayout];
[self layoutIfNeeded];
}];
@@ -21,9 +21,9 @@
/**
The common interface for components that initiate liking.
- See:FBSDKLikeButton
@see FBSDKLikeButton
- See:FBSDKLikeControl
@see FBSDKLikeControl
*/
@protocol FBSDKLiking <NSObject>
@@ -23,32 +23,24 @@
/**
A dialog for sharing content through Messenger.
DEPRECATION WARNING: AS OF THE JULY 2018 RELEASE, FBSDKMessageDialog WILL STOP SUPPORTING
SOME OF THE EXISTING FBSDKSharingContent TYPES. validateWithError WILL RETURN NO WITH AN
ERROR FOR UNSUPPORTED TYPES, AND TRYING TO show UNSUPPOTED CONTENT WILL CALL
sharer: didFailWithError: ON THE DELEGATE. THE FOLLOWING SHARE TYPES WILL CONTINUE TO BE
SUPPORTED ON AND AFTER JULY 2018:
SUPPORTED SHARE TYPES
- FBSDKShareLinkContent
- FBSDKShareMessengerOpenGraphMusicTemplateContent
- FBSDKShareMessengerMediaTemplateContent
- FBSDKShareMessengerGenericTemplateContent
THE FOLLOWING WILL NO LONGER BE SUPPORTED AS OF JULY 2018:
UNSUPPORTED SHARE TYPES (DEPRECATED AUGUST 2018)
- FBSDKShareOpenGraphContent
- FBSDKSharePhotoContent
- FBSDKShareVideoContent
- Any other types that are not one of the four supported types listed above
FBSDKShareMessengerMediaTemplateContent and FBSDKShareMessengerGenericTemplateContent
SHOULD BE ABLE TO REPLACE THE FUNCTIONALITY OF FBSDKSharePhotoContent AND
FBSDKShareVideoContent, SO CONSIDER MIGRATING TO THESE NEW SHARE TYPES.
*/
@interface FBSDKMessageDialog : NSObject <FBSDKSharingDialog>
/**
Convenience method to show a Message Share Dialog with content and a delegate.
- Parameter content: The content to be shared.
- Parameter delegate: The receiver's delegate.
@param content The content to be shared.
@param delegate The receiver's delegate.
*/
+ (instancetype)showWithContent:(id<FBSDKSharingContent>)content delegate:(id<FBSDKSharingDelegate>)delegate;
@@ -19,6 +19,7 @@
#import "FBSDKMessageDialog.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareCameraEffectContent.h"
#import "FBSDKShareConstants.h"
#import "FBSDKShareDefines.h"
#import "FBSDKShareError.h"
@@ -81,6 +82,7 @@
id<FBSDKSharingContent> shareContent = self.shareContent;
NSDictionary *parameters = [FBSDKShareUtility parametersForShareContent:shareContent
bridgeOptions:FBSDKShareBridgeOptionsDefault
shouldFailOnDataError:self.shouldFailOnDataError];
NSString *methodName = ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]] ?
FBSDK_SHARE_OPEN_GRAPH_METHOD_NAME :
@@ -110,26 +112,24 @@
- (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]) {
if (self.shareContent) {
if ([self.shareContent isKindOfClass:[FBSDKShareLinkContent class]] ||
[self.shareContent isKindOfClass:[FBSDKShareMessengerGenericTemplateContent class]] ||
[self.shareContent isKindOfClass:[FBSDKShareMessengerMediaTemplateContent class]] ||
[self.shareContent isKindOfClass:[FBSDKShareMessengerOpenGraphMusicTemplateContent class]]) {
} else {
if (errorRef != NULL) {
NSString *message = [NSString stringWithFormat:@"Message dialog does not support %@.",
NSStringFromClass(self.shareContent.class)];
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent"
message:message];
}
return NO;
}
}
if ([shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent"
message:@"Message dialog does not support camera content."];
}
return NO;
}
return [FBSDKShareUtility validateShareContent:self.shareContent error:errorRef];
return [FBSDKShareUtility validateShareContent:self.shareContent
bridgeOptions:FBSDKShareBridgeOptionsDefault
error:errorRef];
}
#pragma mark - Helper Methods
@@ -35,8 +35,8 @@
/**
Convenience method to build up a share API with content and a delegate.
- Parameter content: The content to be shared.
- Parameter delegate: The receiver's delegate.
@param content The content to be shared.
@param delegate The receiver's delegate.
*/
+ (instancetype)shareWithContent:(id<FBSDKSharingContent>)content delegate:(id<FBSDKSharingDelegate>)delegate;
@@ -66,14 +66,14 @@
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:]
- Returns: YES if the receiver can send, otherwise NO.
@see [FBSDKSharing validateWithError:]
@return YES if the receiver can send, otherwise NO.
*/
- (BOOL)canShare;
/**
Creates an User Owned Open Graph object without an action.
- Parameter openGraphObject: The open graph object to create.
@param openGraphObject The open graph object to create.
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
@@ -81,13 +81,13 @@
Also see https://developers.facebook.com/docs/sharing/opengraph/object-api#objectapi-creatinguser
- Returns: YES if the receiver was able to send the request to create the object, otherwise NO.
@return YES if the receiver was able to send the request to create the object, otherwise NO.
*/
- (BOOL)createOpenGraphObject:(FBSDKShareOpenGraphObject *)openGraphObject;
/**
Begins the send from the receiver.
- Returns: YES if the receiver was able to send the share, otherwise NO.
@return YES if the receiver was able to send the share, otherwise NO.
*/
- (BOOL)share;
@@ -129,7 +129,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
void(^completionHandler)(id) = ^(NSDictionary *result) {
[_delegate sharer:self didCompleteWithResults:result];
[self->_delegate sharer:self didCompleteWithResults:result];
};
if (![self _stageOpenGraphObject:openGraphObject
connection:connection
@@ -199,7 +199,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
if (errorRef != NULL){
*errorRef = nil;
}
return [FBSDKShareUtility validateShareContent:shareContent error:errorRef];
return [FBSDKShareUtility validateShareContent:shareContent bridgeOptions:FBSDKShareBridgeOptionsDefault error:errorRef];
}
- (FBSDKAccessToken *)accessToken
@@ -249,11 +249,11 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
- (BOOL)_shareLinkContent:(FBSDKShareLinkContent *)linkContent
{
FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!_delegate) {
if (!self->_delegate) {
return;
}
if (error) {
[_delegate sharer:self didFailWithError:error];
[self->_delegate sharer:self didFailWithError:error];
} else {
result = [FBSDKTypeUtility dictionaryValue:result];
NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init];
@@ -261,7 +261,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
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];
[self->_delegate sharer:self didCompleteWithResults:shareResults];
}
};
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
@@ -298,21 +298,21 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
FBSDKGraphRequestHandler requestHandler = ^(FBSDKGraphRequestConnection *requestConnection,
id result,
NSError *requestError) {
if (!_delegate) {
if (!self->_delegate) {
return;
}
if (requestError) {
NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode
message:@"Error sharing Open Graph content"
underlyingError:requestError];
[_delegate sharer:self didFailWithError:error];
[self->_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];
[self->_delegate sharer:self didCompleteWithResults:shareResults];
}
};
NSString *graphPath = [self _graphPathWithSuffix:[FBSDKUtility URLEncode:action.actionType], nil];
@@ -364,11 +364,11 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
if (++completedCount != requestCount) {
return;
}
if (!_delegate) {
if (!self->_delegate) {
return;
}
if ([errors count]) {
[_delegate sharer:self didFailWithError:errors[0]];
[self->_delegate sharer:self didFailWithError:errors[0]];
} else if ([results count]) {
NSArray *individualPhotoIDs = [results valueForKeyPath:@"id"];
// each photo upload will be merged into the same post, so grab the post_id from the first and use that
@@ -379,7 +379,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
[FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:firstResult[@"post_id"]]
forKey:FBSDK_SHARE_RESULT_POST_ID_KEY];
[FBSDKInternalUtility dictionary:shareResults setObject:individualPhotoIDs forKey:FBSDK_SHARE_RESULT_PHOTO_IDS_KEY];
[_delegate sharer:self didCompleteWithResults:shareResults];
[self->_delegate sharer:self didCompleteWithResults:shareResults];
}
};
for (FBSDKGraphRequest *request in requests) {
@@ -394,7 +394,10 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
[self _addCommonParameters:parameters content:videoContent];
[FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"description"];
if ([self.accessToken.permissions containsObject:@"ads_management"]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
FBSDKSharePhoto *photo = videoContent.previewPhoto;
#pragma clang diagnostic pop
UIImage *image = photo.image;
if (!image && [photo.imageURL isFileURL]) {
image = [UIImage imageWithContentsOfFile:[photo.imageURL path]];
@@ -428,8 +431,8 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
return NO;
}
[[FBSDKShareAPI defaultAssetsLibrary] assetForURL:videoURL resultBlock:^(ALAsset *asset) {
_assetRepresentation = [asset defaultRepresentation];
NSUInteger size = (NSUInteger)_assetRepresentation.size;
self->_assetRepresentation = [asset defaultRepresentation];
NSUInteger size = (NSUInteger)self->_assetRepresentation.size;
FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[videoURL lastPathComponent]
videoSize:size
parameters:parameters
@@ -437,7 +440,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
videoUploader.graphNode = self.graphNode;
[videoUploader start];
} failureBlock:^(NSError *error) {
[_delegate sharer:self didFailWithError:error];
[self->_delegate sharer:self didFailWithError:error];
}];
return YES;
#endif
@@ -449,7 +452,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
- (BOOL)_addEncodedParametersToDictionary:(NSMutableDictionary *)parameters
key:(NSString *)key
value:(id)value
error:(NSError **)errorRef
error:(NSError * __autoreleasing *)errorRef
{
if ([value isKindOfClass:[NSString class]] ||
[value isKindOfClass:[NSNumber class]] ||
@@ -522,7 +525,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"value"
value:item
message:@"Error staging object."];
[_delegate sharer:self didFailWithError:error];
[self->_delegate sharer:self didFailWithError:error];
itemDidFail();
*stop = YES;
result = NO;
@@ -558,7 +561,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
error:&JSONError
invalidObjectHandler:NULL];
if (!objectString) {
[_delegate sharer:self didFailWithError:JSONError];
[self->_delegate sharer:self didFailWithError:JSONError];
return;
}
NSString *graphPath = [self _graphPathWithSuffix:@"objects", type, nil];
@@ -571,7 +574,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
FBSDKGraphRequestHandler requestCompletionHandler = ^(FBSDKGraphRequestConnection *requestConnection,
id result,
NSError *requestError) {
if (!_delegate) {
if (!self->_delegate) {
return;
}
if (requestError) {
@@ -580,7 +583,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode
message:message
underlyingError:requestError];
[_delegate sharer:self didFailWithError:error];
[self->_delegate sharer:self didFailWithError:error];
} else if (completionHandler != NULL) {
completionHandler([FBSDKTypeUtility dictionaryValue:result]);
}
@@ -635,7 +638,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
if (isAction) {
NSError *error;
if (![self _addEncodedParametersToDictionary:stagedContainer key:key value:stagedValue error:&error]) {
[_delegate sharer:self didFailWithError:error];
[self->_delegate sharer:self didFailWithError:error];
itemDidFail();
return;
}
@@ -687,7 +690,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode
message:@"Error staging photo"
underlyingError:requestError];
[_delegate sharer:self didFailWithError:error];
[self->_delegate sharer:self didFailWithError:error];
} else if (stagingHandler) {
NSMutableDictionary *stagedPhoto = [[NSMutableDictionary alloc] initWithDictionary: @{
@"url": stagedPhotoURLString,
@@ -703,7 +706,7 @@ static NSMutableArray *g_pendingFBSDKShareAPI;
NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"photo"
value:photo
message:@"Photos must have an imageURL or image."];
[_delegate sharer:self didFailWithError:error];
[self->_delegate sharer:self didFailWithError:error];
return NO;
}
}
@@ -21,11 +21,12 @@
#import <FBSDKShareKit/FBSDKCameraEffectArguments.h>
#import <FBSDKShareKit/FBSDKCameraEffectTextures.h>
#import <FBSDKShareKit/FBSDKSharingContent.h>
#import <FBSDKShareKit/FBSDKSharingScheme.h>
/**
A model for content to share with a Facebook camera effect.
*/
@interface FBSDKShareCameraEffectContent : NSObject <FBSDKSharingContent>
@interface FBSDKShareCameraEffectContent : NSObject <FBSDKSharingContent, FBSDKSharingScheme>
/**
ID of the camera effect to use.
@@ -44,8 +45,8 @@
/**
Compares the receiver to another camera effect content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@param content The other content
@return YES if the receiver's values are equal to the other content's values; otherwise NO
*/
- (BOOL)isEqualToShareCameraEffectContent:(FBSDKShareCameraEffectContent *)content;
@@ -18,20 +18,22 @@
#import "FBSDKShareCameraEffectContent.h"
#import "FBSDKCameraEffectArguments+Internal.h"
#import "FBSDKCameraEffectTextures+Internal.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKHashtag.h"
#import "FBSDKShareUtility.h"
static NSString *const FBSDKShareCameraEffectContentEffectIDKey = @"effectID";
static NSString *const FBSDKShareCameraEffectContentEffectArgumentsKey = @"effectArguments";
static NSString *const FBSDKShareCameraEffectContentEffectTexturesKey = @"effectTextures";
static NSString *const FBSDKShareCameraEffectContentContentURLKey = @"contentURL";
static NSString *const FBSDKShareCameraEffectContentHashtagKey = @"hashtag";
static NSString *const FBSDKShareCameraEffectContentPeopleIDsKey = @"peopleIDs";
static NSString *const FBSDKShareCameraEffectContentPlaceIDKey = @"placeID";
static NSString *const FBSDKShareCameraEffectContentRefKey = @"ref";
static NSString *const FBSDKShareCameraEffectContentPageIDKey = @"pageID";
static NSString *const FBSDKShareCameraEffectContentUUIDKey = @"uuid";
static NSString *const kFBSDKShareCameraEffectContentEffectIDKey = @"effectID";
static NSString *const kFBSDKShareCameraEffectContentEffectArgumentsKey = @"effectArguments";
static NSString *const kFBSDKShareCameraEffectContentEffectTexturesKey = @"effectTextures";
static NSString *const kFBSDKShareCameraEffectContentContentURLKey = @"contentURL";
static NSString *const kFBSDKShareCameraEffectContentHashtagKey = @"hashtag";
static NSString *const kFBSDKShareCameraEffectContentPeopleIDsKey = @"peopleIDs";
static NSString *const kFBSDKShareCameraEffectContentPlaceIDKey = @"placeID";
static NSString *const kFBSDKShareCameraEffectContentRefKey = @"ref";
static NSString *const kFBSDKShareCameraEffectContentPageIDKey = @"pageID";
static NSString *const kFBSDKShareCameraEffectContentUUIDKey = @"uuid";
@implementation FBSDKShareCameraEffectContent
@@ -59,6 +61,77 @@ static NSString *const FBSDKShareCameraEffectContentUUIDKey = @"uuid";
return self;
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
[FBSDKInternalUtility dictionary:parameters
setObject:_effectID
forKey:@"effect_id"];
NSString *effectArgumentsJSON;
if (_effectArguments) {
effectArgumentsJSON = [FBSDKInternalUtility JSONStringForObject:[_effectArguments allArguments]
error:NULL
invalidObjectHandler:NULL];
}
[FBSDKInternalUtility dictionary:parameters
setObject:effectArgumentsJSON
forKey:@"effect_arguments"];
NSData *effectTexturesData;
if (_effectTextures) {
// Convert the entire textures dictionary into one NSData, because
// the existing API protocol only allows one value to be put into the pasteboard.
NSDictionary<NSString *, UIImage *> *texturesDict = [_effectTextures allTextures];
NSMutableDictionary<NSString *, NSData *> *texturesDataDict = [NSMutableDictionary dictionaryWithCapacity:texturesDict.count];
[texturesDict enumerateKeysAndObjectsUsingBlock:^(NSString *key, UIImage *img, BOOL *stop) {
// Convert UIImages to NSData, because UIImage is not archivable.
NSData *imageData = UIImagePNGRepresentation(img);
if (imageData) {
[texturesDataDict setObject:imageData forKey:key];
}
}];
effectTexturesData = [NSKeyedArchiver archivedDataWithRootObject:texturesDataDict];
}
[FBSDKInternalUtility dictionary:parameters
setObject:effectTexturesData
forKey:@"effect_textures"];
}
#pragma mark - FBSDKSharingScheme
- (NSString *)schemeForMode:(FBSDKShareDialogMode)mode
{
if ((FBSDKShareDialogModeNative == mode) || (FBSDKShareDialogModeAutomatic == mode)) {
if ([FBSDKInternalUtility isMSQRDPlayerAppInstalled]) {
// If installed, launch MSQRD Player for testing effects.
return FBSDK_CANOPENURL_MSQRD_PLAYER;
}
}
return nil;
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
if ([_effectID length] > 0) {
NSCharacterSet* nonDigitCharacters = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([_effectID rangeOfCharacterFromSet:nonDigitCharacters].location != NSNotFound) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"effectID"
value:_effectID
message:@"Invalid value for effectID, effectID can contain only numerical characters."];
}
return NO;
}
}
return YES;
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -114,32 +187,32 @@ static NSString *const FBSDKShareCameraEffectContentUUIDKey = @"uuid";
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [self init])) {
_effectID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKShareCameraEffectContentEffectIDKey];
_effectArguments = [decoder decodeObjectOfClass:[FBSDKCameraEffectArguments class] forKey:FBSDKShareCameraEffectContentEffectArgumentsKey];
_effectTextures = [decoder decodeObjectOfClass:[FBSDKCameraEffectTextures class] forKey:FBSDKShareCameraEffectContentEffectTexturesKey];
_contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDKShareCameraEffectContentContentURLKey];
_hashtag = [decoder decodeObjectOfClass:[FBSDKHashtag class] forKey:FBSDKShareCameraEffectContentHashtagKey];
_peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDKShareCameraEffectContentPeopleIDsKey];
_placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKShareCameraEffectContentPlaceIDKey];
_ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKShareCameraEffectContentRefKey];
_pageID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKShareCameraEffectContentPageIDKey];
_shareUUID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKShareCameraEffectContentUUIDKey];
_effectID = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKShareCameraEffectContentEffectIDKey];
_effectArguments = [decoder decodeObjectOfClass:[FBSDKCameraEffectArguments class] forKey:kFBSDKShareCameraEffectContentEffectArgumentsKey];
_effectTextures = [decoder decodeObjectOfClass:[FBSDKCameraEffectTextures class] forKey:kFBSDKShareCameraEffectContentEffectTexturesKey];
_contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:kFBSDKShareCameraEffectContentContentURLKey];
_hashtag = [decoder decodeObjectOfClass:[FBSDKHashtag class] forKey:kFBSDKShareCameraEffectContentHashtagKey];
_peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:kFBSDKShareCameraEffectContentPeopleIDsKey];
_placeID = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKShareCameraEffectContentPlaceIDKey];
_ref = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKShareCameraEffectContentRefKey];
_pageID = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKShareCameraEffectContentPageIDKey];
_shareUUID = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKShareCameraEffectContentUUIDKey];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:_effectID forKey:FBSDKShareCameraEffectContentEffectIDKey];
[encoder encodeObject:_effectArguments forKey:FBSDKShareCameraEffectContentEffectArgumentsKey];
[encoder encodeObject:_effectTextures forKey:FBSDKShareCameraEffectContentEffectTexturesKey];
[encoder encodeObject:_contentURL forKey:FBSDKShareCameraEffectContentContentURLKey];
[encoder encodeObject:_hashtag forKey:FBSDKShareCameraEffectContentHashtagKey];
[encoder encodeObject:_peopleIDs forKey:FBSDKShareCameraEffectContentPeopleIDsKey];
[encoder encodeObject:_placeID forKey:FBSDKShareCameraEffectContentPlaceIDKey];
[encoder encodeObject:_ref forKey:FBSDKShareCameraEffectContentRefKey];
[encoder encodeObject:_pageID forKey:FBSDKShareCameraEffectContentPageIDKey];
[encoder encodeObject:_shareUUID forKey:FBSDKShareCameraEffectContentUUIDKey];
[encoder encodeObject:_effectID forKey:kFBSDKShareCameraEffectContentEffectIDKey];
[encoder encodeObject:_effectArguments forKey:kFBSDKShareCameraEffectContentEffectArgumentsKey];
[encoder encodeObject:_effectTextures forKey:kFBSDKShareCameraEffectContentEffectTexturesKey];
[encoder encodeObject:_contentURL forKey:kFBSDKShareCameraEffectContentContentURLKey];
[encoder encodeObject:_hashtag forKey:kFBSDKShareCameraEffectContentHashtagKey];
[encoder encodeObject:_peopleIDs forKey:kFBSDKShareCameraEffectContentPeopleIDsKey];
[encoder encodeObject:_placeID forKey:kFBSDKShareCameraEffectContentPlaceIDKey];
[encoder encodeObject:_ref forKey:kFBSDKShareCameraEffectContentRefKey];
[encoder encodeObject:_pageID forKey:kFBSDKShareCameraEffectContentPageIDKey];
[encoder encodeObject:_shareUUID forKey:kFBSDKShareCameraEffectContentUUIDKey];
}
#pragma mark - NSCopying
@@ -29,9 +29,9 @@
/**
Convenience method to show an FBSDKShareDialog with a fromViewController, content and a delegate.
- Parameter viewController: A UIViewController to present the dialog from, if appropriate.
- Parameter content: The content to be shared.
- Parameter delegate: The receiver's 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
@@ -21,6 +21,7 @@
#import <Social/Social.h>
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareCameraEffectContent.h"
#import "FBSDKShareConstants.h"
#import "FBSDKShareDefines.h"
#import "FBSDKShareError.h"
@@ -110,7 +111,12 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
- (BOOL)canShow
{
if (!self.shareContent) {
if (self.shareContent) {
// Validate this content
NSError *error = nil;
return [self _validateWithError:&error];
} else {
// Launch an empty dialog for sharing a status message.
switch (self.mode) {
case FBSDKShareDialogModeAutomatic:
case FBSDKShareDialogModeBrowser:
@@ -126,9 +132,6 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
return [self _canShowShareSheet];
}
}
} else {
NSError *error = nil;
return [self _validateWithError:&error];
}
}
@@ -265,16 +268,6 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
(!useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef]));
}
- (NSString *)_nativeScheme {
if ([self.shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) {
if ([FBSDKInternalUtility isMSQRDPlayerAppInstalled]) {
// If installed, launch MSQRD Player for testing effects.
return FBSDK_CANOPENURL_MSQRD_PLAYER;
}
}
return FBSDK_CANOPENURL_FACEBOOK;
}
- (void)_loadNativeMethodName:(NSString **)methodNameRef methodVersion:(NSString **)methodVersionRef
{
if (methodNameRef != NULL) {
@@ -496,7 +489,7 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
- (BOOL)_showBrowser:(NSError **)errorRef
{
if (![self _validateShareContentForBrowser:errorRef]) {
if (![self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]) {
return NO;
}
id<FBSDKSharingContent> shareContent = self.shareContent;
@@ -602,15 +595,22 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
if (![self _validateShareContentForNative:validationErrorRef]) {
return NO;
}
NSString *scheme = nil;
if ([self.shareContent respondsToSelector:@selector(schemeForMode:)]) {
scheme = [(id<FBSDKSharingScheme>)self.shareContent schemeForMode:FBSDKShareDialogModeNative];
}
if (!(scheme.length > 0)) {
scheme = FBSDK_CANOPENURL_FACEBOOK;
}
NSString *methodName;
NSString *methodVersion;
[self _loadNativeMethodName:&methodName methodVersion:&methodVersion];
NSDictionary *parameters = [FBSDKShareUtility parametersForShareContent:self.shareContent
bridgeOptions:FBSDKShareBridgeOptionsDefault
shouldFailOnDataError:self.shouldFailOnDataError];
FBSDKBridgeAPIRequest *request;
request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative
scheme:[self _nativeScheme]
scheme:scheme
methodName:methodName
methodVersion:methodVersion
parameters:parameters
@@ -717,7 +717,7 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
- (BOOL)_showWeb:(NSError **)errorRef
{
if (![self _validateShareContentForBrowser:errorRef]) {
if (![self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsPhotoImageURL error:errorRef]) {
return NO;
}
id<FBSDKSharingContent> shareContent = self.shareContent;
@@ -758,33 +758,38 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
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]) {
if (self.shareContent) {
if ([self.shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]] ||
[self.shareContent isKindOfClass:[FBSDKShareLinkContent class]] ||
[self.shareContent isKindOfClass:[FBSDKShareMediaContent class]] ||
[self.shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]] ||
[self.shareContent isKindOfClass:[FBSDKSharePhotoContent class]] ||
[self.shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
} else {
if (errorRef != NULL) {
NSString *message = [NSString stringWithFormat:@"Share dialog does not support %@.",
NSStringFromClass(self.shareContent.class)];
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent"
message:message];
}
return NO;
}
}
if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) {
if (![FBSDKShareUtility validateAssetLibraryURLsWithShareMediaContent:(FBSDKShareMediaContent *)shareContent name:@"mediaVideoURL" error:errorRef]) {
return NO;
}
if (![FBSDKShareUtility validateShareContent:self.shareContent
bridgeOptions:FBSDKShareBridgeOptionsDefault
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]);
[self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]);
}
case FBSDKShareDialogModeNative:{
return [self _validateShareContentForNative:errorRef];
@@ -792,15 +797,23 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
case FBSDKShareDialogModeShareSheet:{
return [self _validateShareContentForShareSheet:errorRef];
}
case FBSDKShareDialogModeBrowser:
case FBSDKShareDialogModeBrowser:{
return [self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef];
}
case FBSDKShareDialogModeWeb:{
return [self _validateShareContentForBrowser:errorRef];
return [self _validateShareContentForBrowserWithOptions:FBSDKShareBridgeOptionsPhotoImageURL error:errorRef];
}
case FBSDKShareDialogModeFeedBrowser:
case FBSDKShareDialogModeFeedWeb:{
return [self _validateShareContentForFeed:errorRef];
}
}
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"FBSDKShareDialogMode"
value:@(self.mode)
message:nil];
}
return NO;
}
/**
@@ -834,9 +847,21 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
return YES;
}
- (BOOL)_validateShareContentForBrowser:(NSError **)errorRef
- (BOOL)_validateShareContentForBrowserWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
id<FBSDKSharingContent> shareContent = self.shareContent;
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
// The parameter 'href' or 'media' is required
FBSDKShareLinkContent *const linkContent = shareContent;
if (!linkContent.contentURL) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"FBSDKShareLinkContent contentURL is required."];
}
return NO;
}
}
if ([shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
@@ -847,18 +872,21 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
}
BOOL containsMedia;
BOOL containsPhotos;
[FBSDKShareUtility testShareContent:shareContent containsMedia:&containsMedia containsPhotos:&containsPhotos containsVideos:NULL];
BOOL containsVideos;
[FBSDKShareUtility testShareContent:shareContent containsMedia:&containsMedia containsPhotos:&containsPhotos containsVideos:&containsVideos];
if (containsPhotos) {
if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
if ([FBSDKAccessToken currentAccessToken] != nil) {
return YES;
}
if ([FBSDKAccessToken currentAccessToken] == nil) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"The web share dialog needs a valid access token to stage photos."];
}
return NO;
}
if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
if (![shareContent validateWithOptions:bridgeOptions error:errorRef]) {
return NO;
}
} else {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
@@ -868,13 +896,30 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
return NO;
}
}
if (containsMedia) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"Web share dialogs cannot include local media."];
if (containsVideos) {
if ([FBSDKAccessToken currentAccessToken] == nil) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"The web share dialog needs a valid access token to stage videos."];
}
return NO;
}
if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
if (![shareContent validateWithOptions:bridgeOptions error:errorRef]) {
return NO;
}
}
}
if (containsMedia) {
if (bridgeOptions & FBSDKShareBridgeOptionsPhotoImageURL) { // a web-based URL is required
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"Web share dialogs cannot include local media."];
}
return NO;
}
return NO;
}
return YES;
}
@@ -882,20 +927,24 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
- (BOOL)_validateShareContentForFeed:(NSError **)errorRef
{
id<FBSDKSharingContent> shareContent = self.shareContent;
if (![shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
// The parameter 'href' or 'media' is required
FBSDKShareLinkContent *const linkContent = shareContent;
if (!linkContent.contentURL) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"FBSDKShareLinkContent contentURL is required."];
}
return NO;
}
} else {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"Feed share dialogs support FBSDKShareLinkContent."];
}
return NO;
} else if ([shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"Camera Content must be shared in `Native` mode."];
}
return NO;
}
return YES;
}
@@ -916,69 +965,55 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
if (![shareContent isKindOfClass:[FBSDKShareVideoContent class]]) {
return YES;
}
return [self _validateVideoURL:((FBSDKShareVideoContent *)shareContent).video.videoURL error:errorRef];
return [(FBSDKShareVideoContent *)shareContent validateWithOptions:FBSDKShareBridgeOptionsDefault
error:errorRef];
}
- (BOOL)_validateShareContentForShareSheet:(NSError **)errorRef
{
id<FBSDKSharingContent> shareContent = self.shareContent;
if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
if ([self _contentImages].count != 0) {
if (shareContent) {
if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) {
if ([self _contentImages].count != 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] &&
[(FBSDKShareVideoContent *)shareContent validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]);
} else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) {
return ([self _canUseFBShareSheet] &&
[self _validateShareMediaContentAvailability:shareContent error:errorRef] &&
[(FBSDKShareMediaContent *)shareContent validateWithOptions:FBSDKShareBridgeOptionsDefault error:errorRef]);
} else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
FBSDKShareOpenGraphContent *ogContent = (FBSDKShareOpenGraphContent *)shareContent;
BOOL isOGURLShare = [self _isOpenGraphURLShare:ogContent];
BOOL isValidOGShare = (isOGURLShare &&
[ogContent.action.actionType length] != 0 &&
[ogContent.previewPropertyName length] != 0);
if (!isValidOGShare) {
if ((errorRef != NULL) && !*errorRef) {
NSString *message = @"Share content must include an URL in the action, an action type, and a preview property name in order to share with the share sheet.";
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message];
}
}
return isValidOGShare;
} else if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
return YES;
} else {
if ((errorRef != NULL) && !*errorRef) {
NSString *message = @"Share photo content must have UIImage photos in order to share with the share sheet";
NSString *message = [NSString stringWithFormat:@"Share sheet does not support %@.",
NSStringFromClass(shareContent.class)];
*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:[FBSDKShareMediaContent class]]) {
return ([self _canUseFBShareSheet] &&
[self _validateShareMediaContentAvailability:shareContent error:errorRef] &&
[FBSDKShareUtility validateShareMediaContent:(FBSDKShareMediaContent *)shareContent error:errorRef]);
} else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
FBSDKShareOpenGraphContent *ogContent = (FBSDKShareOpenGraphContent *)shareContent;
BOOL isOGURLShare = [self _isOpenGraphURLShare:ogContent];
BOOL isValidOGShare = (isOGURLShare &&
[ogContent.action.actionType length] != 0 &&
[ogContent.previewPropertyName length] != 0);
if (!isValidOGShare) {
if ((errorRef != NULL) && !*errorRef) {
NSString *message = @"Share content must include an URL in the action, an action type, and a preview property name in order to share with the share sheet.";
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message];
}
}
return isValidOGShare;
} else if (![shareContent isKindOfClass:[FBSDKShareLinkContent class]]) {
if ((errorRef != NULL) && !*errorRef) {
NSString *message = @"Share content must be FBSDKShareLinkContent or FBSDKShareMediaContent in order to share "
@"with the share sheet.";
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message];
}
return NO;
} else if ([shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent"
value:shareContent
message:@"Camera Content must be shared in `Native` mode."];
}
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;
}
@@ -1060,7 +1095,6 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
contentType = FBSDKAppEventsDialogShareContentTypeUnknown;
}
NSDictionary *parameters = @{
FBSDKAppEventParameterDialogMode : shareMode,
FBSDKAppEventParameterDialogShareContentType : contentType,
@@ -1091,6 +1125,7 @@ FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredF
}
if ([self.shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
NSDictionary *ogData = [FBSDKShareUtility parametersForShareContent:self.shareContent
bridgeOptions:FBSDKShareBridgeOptionsDefault
shouldFailOnDataError:self.shouldFailOnDataError];
initialTextDictionary[@"og_data"] = ogData;
}
@@ -60,6 +60,6 @@ typedef NS_ENUM(NSUInteger, FBSDKShareDialogMode)
};
/**
Converts an FBLikeControlObjectType to an NSString.
Converts an FBSDKShareDialogMode to an NSString.
*/
FBSDK_EXTERN NSString *NSStringFromFBSDKShareDialogMode(FBSDKShareDialogMode dialogMode);
@@ -30,7 +30,7 @@
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).
- Returns: The description of the link
@return The description of the link
@deprecated `contentDescription` is deprecated from Graph API 2.9.
For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations.
@@ -42,7 +42,7 @@
The title to display for this link.
This value may be discarded for specially handled links (ex: iTunes URLs).
- Returns: The link title
@return The link title
@deprecated `contentTitle` is deprecated from Graph API 2.9.
For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations
@@ -52,7 +52,7 @@
/**
The URL of a picture to attach to this content.
- Returns: The network URL of an image
@return The network URL of an image
@deprecated `imageURL` is deprecated from Graph API 2.9.
For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations
@@ -64,14 +64,14 @@
Some quote text of the link.
If specified, the quote text will render with custom styling on top of the link.
- Returns: The quote text of a link
@return The quote text of a link
*/
@property (nonatomic, copy) NSString *quote;
/**
Compares the receiver to another link content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@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;
@@ -77,6 +77,39 @@
}
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
[FBSDKInternalUtility dictionary:parameters setObject:_contentURL forKey:@"link"];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[FBSDKInternalUtility dictionary:parameters setObject:_contentTitle forKey:@"name"];
[FBSDKInternalUtility dictionary:parameters setObject:_contentDescription forKey:@"description"];
[FBSDKInternalUtility dictionary:parameters setObject:_imageURL forKey:@"picture"];
#pragma clang diagnostic pop
[FBSDKInternalUtility dictionary:parameters setObject:_quote forKey:@"quote"];
/**
Pass link parameter as "messenger_link" due to versioning requirements for message dialog flow.
We will only use the new share flow we developed if messenger_link is present, not link.
*/
[FBSDKInternalUtility dictionary:parameters setObject:_contentURL forKey:@"messenger_link"];
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return ([FBSDKShareUtility validateNetworkURL:_contentURL name:@"contentURL" error:errorRef] &&
[FBSDKShareUtility validateNetworkURL:_imageURL name:@"imageURL" error:errorRef]);
#pragma clang diagnostic pop
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -27,14 +27,14 @@
/**
Media to be shared.
- Returns: Array of the media (FBSDKSharePhoto or FBSDKShareVideo)
@return Array of the media (FBSDKSharePhoto or FBSDKShareVideo)
*/
@property (nonatomic, copy) NSArray *media;
/**
Compares the receiver to another media content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@param content The other content
@return YES if the receiver's values are equal to the other content's values; otherwise NO
*/
- (BOOL)isEqualToShareMediaContent:(FBSDKShareMediaContent *)content;
@@ -20,6 +20,7 @@
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKHashtag.h"
#import "FBSDKShareError.h"
#import "FBSDKSharePhoto.h"
#import "FBSDKShareUtility.h"
#import "FBSDKShareVideo.h"
@@ -74,6 +75,63 @@
}
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
// FBSDKShareMediaContent is currently available via the Share extension only (thus no parameterization implemented at this time)
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
if (![FBSDKShareUtility validateArray:_media minCount:1 maxCount:20 name:@"photos" error:errorRef]) {
return NO;
}
int videoCount = 0;
for (id media in _media) {
if ([media isKindOfClass:[FBSDKSharePhoto class]]) {
FBSDKSharePhoto *photo = (FBSDKSharePhoto *)media;
if (![photo validateWithOptions:bridgeOptions error:NULL]) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media"
value:media
message:@"photos must have UIImages"];
}
return NO;
}
} else if ([media isKindOfClass:[FBSDKShareVideo class]]) {
if (videoCount > 0) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media"
value:media
message:@"Only 1 video is allowed"];
return NO;
}
}
videoCount++;
FBSDKShareVideo *video = (FBSDKShareVideo *)media;
if (![FBSDKShareUtility validateRequiredValue:video name:@"video" error:errorRef]) {
return NO;
}
if (![video validateWithOptions:bridgeOptions error:errorRef]) {
return NO;
}
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media"
value:media
message:@"Only FBSDKSharePhoto and FBSDKShareVideo are allowed in `media` property"];
}
return NO;
}
}
return YES;
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -27,7 +27,7 @@
/**
The title displayed to the user for the button.
- Returns: The title for the button.
@return The title for the button.
*/
@property (nonatomic, copy) NSString *title;
@@ -18,7 +18,11 @@
#import "FBSDKShareMessengerGenericTemplateContent.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareMessengerContentUtility.h"
#import "FBSDKShareMessengerGenericTemplateElement.h"
#import "FBSDKShareMessengerURLActionButton.h"
#import "FBSDKShareUtility.h"
static NSString *const kGenericTemplatePageIDKey = @"pageID";
static NSString *const kGenericTemplateUUIDKey = @"UUID";
@@ -26,6 +30,35 @@ static NSString *const kGenericTemplateIsSharableKey = @"isSharable";
static NSString *const kGenericTemplateImageAspectRatioKey = @"imageAspectRatio";
static NSString *const kGenericTemplateElementKey = @"element";
static NSString *_ImageAspectRatioString(FBSDKShareMessengerGenericTemplateImageAspectRatio imageAspectRatio)
{
switch (imageAspectRatio) {
case FBSDKShareMessengerGenericTemplateImageAspectRatioSquare:
return @"square";
case FBSDKShareMessengerGenericTemplateImageAspectRatioHorizontal:
return @"horizontal";
}
}
static NSArray<NSDictionary<NSString *, id> *> *_SerializableGenericTemplateElementsFromElements(NSArray<FBSDKShareMessengerGenericTemplateElement *> *elements)
{
NSMutableArray<NSDictionary<NSString *, id> *> *serializableElements = [NSMutableArray array];
for (FBSDKShareMessengerGenericTemplateElement *element in elements) {
NSMutableDictionary<NSString *, id> *elementDictionary = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:elementDictionary setObject:element.title forKey:@"title"];
[FBSDKInternalUtility dictionary:elementDictionary setObject:element.subtitle forKey:@"subtitle"];
[FBSDKInternalUtility dictionary:elementDictionary setObject:element.imageURL.absoluteString forKey:@"image_url"];
[FBSDKInternalUtility dictionary:elementDictionary setObject:SerializableButtonsFromButton(element.button) forKey:kFBSDKShareMessengerButtonsKey];
if ([element.defaultAction isKindOfClass:[FBSDKShareMessengerURLActionButton class]]) {
[FBSDKInternalUtility dictionary:elementDictionary setObject:SerializableButtonFromURLButton(element.defaultAction, YES) forKey:@"default_action"];
}
[serializableElements addObject:elementDictionary];
}
return serializableElements;
}
@implementation FBSDKShareMessengerGenericTemplateContent
#pragma mark - Properties
@@ -49,6 +82,57 @@ static NSString *const kGenericTemplateElementKey = @"element";
return self;
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
NSMutableDictionary<NSString *, id> *payload = [NSMutableDictionary dictionary];
[payload setObject:@"generic" forKey:kFBSDKShareMessengerTemplateTypeKey];
[payload setObject:@(_isSharable) forKey:@"sharable"];
[payload setObject:_ImageAspectRatioString(_imageAspectRatio) forKey:@"image_aspect_ratio"];
[payload setObject:_SerializableGenericTemplateElementsFromElements(@[_element]) forKey:kFBSDKShareMessengerElementsKey];
NSMutableDictionary<NSString *, id> *attachment = [NSMutableDictionary dictionary];
[attachment setObject:kFBSDKShareMessengerTemplateKey forKey:kFBSDKShareMessengerTypeKey];
[attachment setObject:payload forKey:kFBSDKShareMessengerPayloadKey];
NSMutableDictionary<NSString
*, id> *contentForShare = [NSMutableDictionary dictionary];
[contentForShare setObject:attachment forKey:kFBSDKShareMessengerAttachmentKey];
FBSDKShareMessengerGenericTemplateElement *firstElement = _element;
NSMutableDictionary<NSString *, id> *contentForPreview = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:contentForPreview setObject:@"DEFAULT" forKey:@"preview_type"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:firstElement.title forKey:@"title"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:firstElement.subtitle forKey:@"subtitle"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:firstElement.imageURL.absoluteString forKey:@"image_url"];
if (firstElement.button) {
AddToContentPreviewDictionaryForButton(contentForPreview, firstElement.button);
} else {
AddToContentPreviewDictionaryForButton(contentForPreview, firstElement.defaultAction);
}
[FBSDKShareMessengerContentUtility addToParameters:parameters contentForShare:contentForShare contentForPreview:contentForPreview];
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
return [FBSDKShareUtility validateRequiredValue:_element.title
name:@"element.title"
error:errorRef]
&& [FBSDKShareMessengerContentUtility validateMessengerActionButton:_element.defaultAction
isDefaultActionButton:YES
pageID:_pageID
error:errorRef]
&& [FBSDKShareMessengerContentUtility validateMessengerActionButton:_element.button
isDefaultActionButton:NO
pageID:_pageID
error:errorRef];
}
#pragma mark - NSCoding
+ (BOOL)supportsSecureCoding
@@ -20,7 +20,8 @@
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKHashtag.h"
#import "FBSDKShareUtility.h"
#import "FBSDKShareError.h"
#import "FBSDKShareMessengerContentUtility.h"
static NSString *const kMediaTemplatePageIDKey = @"pageID";
static NSString *const kMediaTemplateMediaTypeKey = @"mediaType";
@@ -29,6 +30,55 @@ static NSString *const kMediaTemplateMediaURLKey = @"mediaURL";
static NSString *const kMediaTemplateButtonKey = @"button";
static NSString *const kMediaTemplateUUIDKey = @"uuid";
static BOOL _URLHasFacebookDomain(NSURL *URL)
{
NSString *urlHost = [URL.host lowercaseString];
NSArray<NSString *> *pathComponents = [URL pathComponents];
/**
Check the following three different cases...
1. Check if host is facebook.com, such as in 'https://facebok.com/test'
2. Check if host is someprefix.facebook.com, such as in 'https://www.facebook.com/test'
3. Check if host is null, but the first path component is facebook.com
*/
return [urlHost isEqualToString:@"facebook.com"] ||
[urlHost hasSuffix:@".facebook.com"] ||
([[[pathComponents firstObject] lowercaseString] hasSuffix:@"facebook.com"]);
}
static NSString *_MediaTemplateURLSerializationKey(NSURL *mediaURL)
{
if (_URLHasFacebookDomain(mediaURL)) {
return @"facebook_media_url";
} else {
return @"image_url";
}
}
static NSString *_MediaTypeString(FBSDKShareMessengerMediaTemplateMediaType mediaType)
{
switch (mediaType) {
case FBSDKShareMessengerMediaTemplateMediaTypeImage:
return @"image";
case FBSDKShareMessengerMediaTemplateMediaTypeVideo:
return @"video";
}
}
static NSArray<NSDictionary<NSString *, id> *> *_SerializableMediaTemplateContentFromContent(FBSDKShareMessengerMediaTemplateContent *mediaTemplateContent)
{
NSMutableArray<NSDictionary<NSString *, id> *> *serializableMediaTemplateContent = [NSMutableArray array];
NSMutableDictionary<NSString *, id> *mediaTemplateContentDictionary = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:_MediaTypeString(mediaTemplateContent.mediaType) forKey:@"media_type"];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:mediaTemplateContent.mediaURL.absoluteString forKey:@"url"];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:mediaTemplateContent.attachmentID forKey:@"attachment_id"];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:SerializableButtonsFromButton(mediaTemplateContent.button) forKey:kFBSDKShareMessengerButtonsKey];
[serializableMediaTemplateContent addObject:mediaTemplateContentDictionary];
return serializableMediaTemplateContent;
}
@implementation FBSDKShareMessengerMediaTemplateContent
#pragma mark - Properties
@@ -63,6 +113,50 @@ static NSString *const kMediaTemplateUUIDKey = @"uuid";
return self;
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
NSMutableDictionary<NSString *, id> *payload = [NSMutableDictionary dictionary];
[payload setObject:@"media" forKey:kFBSDKShareMessengerTemplateTypeKey];
[payload setObject:_SerializableMediaTemplateContentFromContent(self) forKey:kFBSDKShareMessengerElementsKey];
NSMutableDictionary<NSString *, id> *attachment = [NSMutableDictionary dictionary];
[attachment setObject:kFBSDKShareMessengerTemplateKey forKey:kFBSDKShareMessengerTypeKey];
[attachment setObject:payload forKey:kFBSDKShareMessengerPayloadKey];
NSMutableDictionary<NSString *, id> *contentForShare = [NSMutableDictionary dictionary];
[contentForShare setObject:attachment forKey:kFBSDKShareMessengerAttachmentKey];
NSMutableDictionary<NSString *, id> *contentForPreview = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:contentForPreview setObject:@"DEFAULT" forKey:@"preview_type"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:_attachmentID forKey:@"attachment_id"];
[FBSDKInternalUtility dictionary:contentForPreview
setObject:_mediaURL.absoluteString
forKey:_MediaTemplateURLSerializationKey(_mediaURL)];
[FBSDKInternalUtility dictionary:contentForPreview setObject:_MediaTypeString(_mediaType) forKey:@"media_type"];
AddToContentPreviewDictionaryForButton(contentForPreview, _button);
[FBSDKShareMessengerContentUtility addToParameters:parameters contentForShare:contentForShare contentForPreview:contentForPreview];
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
if (!_mediaURL && !_attachmentID) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"attachmentID/mediaURL" message:@"Must specify either attachmentID or mediaURL"];
}
return NO;
}
return [FBSDKShareMessengerContentUtility validateMessengerActionButton:_button
isDefaultActionButton:NO
pageID:_pageID
error:errorRef];
}
#pragma mark - NSCoding
+ (BOOL)supportsSecureCoding
@@ -18,11 +18,27 @@
#import "FBSDKShareMessengerOpenGraphMusicTemplateContent.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareMessengerContentUtility.h"
#import "FBSDKShareUtility.h"
static NSString *const kMusicTemplatePageIDKey = @"pageID";
static NSString *const kMusicTemplateURLKey = @"url";
static NSString *const kMusicTemplateButtonKey = @"button";
static NSString *const kMusicTemplateUUIDKey = @"uuid";
static NSArray<NSDictionary<NSString *, id> *> *_SerializableOpenGraphMusicTemplateContentFromContent(FBSDKShareMessengerOpenGraphMusicTemplateContent *openGraphMusicTemplateContent)
{
NSMutableArray<NSDictionary<NSString *, id> *> *serializableOpenGraphMusicTemplateContent = [NSMutableArray array];
NSMutableDictionary<NSString *, id> *openGraphMusicTemplateContentDictionary = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:openGraphMusicTemplateContentDictionary setObject:openGraphMusicTemplateContent.url.absoluteString forKey:@"url"];
[FBSDKInternalUtility dictionary:openGraphMusicTemplateContentDictionary setObject:SerializableButtonsFromButton(openGraphMusicTemplateContent.button) forKey:kFBSDKShareMessengerButtonsKey];
[serializableOpenGraphMusicTemplateContent addObject:openGraphMusicTemplateContentDictionary];
return serializableOpenGraphMusicTemplateContent;
}
@implementation FBSDKShareMessengerOpenGraphMusicTemplateContent
#pragma mark - Properties
@@ -46,6 +62,42 @@ static NSString *const kMusicTemplateUUIDKey = @"uuid";
return self;
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
NSMutableDictionary<NSString *, id> *payload = [NSMutableDictionary dictionary];
[payload setObject:@"open_graph" forKey:kFBSDKShareMessengerTemplateTypeKey];
[payload setObject:_SerializableOpenGraphMusicTemplateContentFromContent(self) forKey:kFBSDKShareMessengerElementsKey];
NSMutableDictionary<NSString *, id> *attachment = [NSMutableDictionary dictionary];
[attachment setObject:kFBSDKShareMessengerTemplateKey forKey:kFBSDKShareMessengerTypeKey];
[attachment setObject:payload forKey:kFBSDKShareMessengerPayloadKey];
NSMutableDictionary<NSString *, id> *contentForShare = [NSMutableDictionary dictionary];
[contentForShare setObject:attachment forKey:kFBSDKShareMessengerAttachmentKey];
NSMutableDictionary<NSString *, id> *contentForPreview = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:contentForPreview setObject:@"OPEN_GRAPH" forKey:@"preview_type"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:_url.absoluteString forKey:@"open_graph_url"];
AddToContentPreviewDictionaryForButton(contentForPreview, _button);
[FBSDKShareMessengerContentUtility addToParameters:parameters contentForShare:contentForShare contentForPreview:contentForPreview];
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
return [FBSDKShareUtility validateRequiredValue:_url name:@"url" error:errorRef]
&& [FBSDKShareUtility validateRequiredValue:_pageID name:@"pageID" error:errorRef]
&& [FBSDKShareMessengerContentUtility validateMessengerActionButton:_button
isDefaultActionButton:NO
pageID:_pageID
error:errorRef];
}
#pragma mark - NSCoding
+ (BOOL)supportsSecureCoding
@@ -32,38 +32,38 @@
/**
Convenience method to build a new action and set the object for the specified key.
- Parameter actionType: The action type of the receiver
- Parameter object: The Open Graph object represented by this action
- Parameter key: The key for the object
@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;
/**
Convenience method to build a new action and set the object for the specified key.
- Parameter actionType: The action type of the receiver
- Parameter objectID: The ID of an existing Open Graph object
- Parameter key: The key for the object
@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;
/**
Convenience method to build a new action and set the object for the specified key.
- Parameter actionType: The action type of the receiver
- Parameter objectURL: The URL to a page that defines the Open Graph object with meta tags
- Parameter key: The key for the object
@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;
/**
Gets the action type.
- Returns: The action type
@return The action type
*/
@property (nonatomic, copy) NSString *actionType;
/**
Compares the receiver to another Open Graph Action.
- Parameter action: The other action
- Returns: YES if the receiver's values are equal to the other action's values; otherwise NO
@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;
@@ -28,7 +28,7 @@
/**
Open Graph Action to be shared.
- Returns: The action
@return The action
*/
@property (nonatomic, copy) FBSDKShareOpenGraphAction *action;
@@ -36,14 +36,14 @@
Property name that points to the primary Open Graph Object in the action.
The value that this action points to will be use for rendering the preview for the share.
- Returns: The property name for the Open Graph Object in the action
@return The property name for the Open Graph Object in the action
*/
@property (nonatomic, copy) NSString *previewPropertyName;
/**
Compares the receiver to another Open Graph content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@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;
@@ -66,6 +66,30 @@
}
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
NSString *previewPropertyName = [FBSDKShareUtility getOpenGraphNameAndNamespaceFromFullName:_previewPropertyName namespace:nil];
[FBSDKInternalUtility dictionary:parameters
setObject:previewPropertyName
forKey:@"previewPropertyName"];
[FBSDKInternalUtility dictionary:parameters setObject:_action.actionType forKey:@"actionType"];
[FBSDKInternalUtility dictionary:parameters
setObject:[FBSDKShareUtility convertOpenGraphValueContainer:_action requireNamespace:NO]
forKey:@"action"];
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
return ([FBSDKShareUtility validateRequiredValue:_action name:@"action" error:errorRef] &&
[FBSDKShareUtility validateRequiredValue:_previewPropertyName name:@"previewPropertyName" error:errorRef] &&
[FBSDKShareUtility validateRequiredValue:_action[_previewPropertyName] name:_previewPropertyName error:errorRef]);
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -45,14 +45,14 @@
/**
Convenience method to build a new action and set the object for the specified key.
- Parameter properties: Properties for the Open Graph object, which will be parsed into the proper models
@param properties Properties for the Open Graph object, which will be parsed into the proper models
*/
+ (instancetype)objectWithProperties:(NSDictionary *)properties;
/**
Compares the receiver to another Open Graph Object.
- Parameter object: The other object
- Returns: YES if the receiver's values are equal to the other object's values; otherwise NO
@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;
@@ -30,66 +30,66 @@
/**
Gets an NSArray out of the receiver.
- Parameter key: The key for the value
- Returns: The NSArray value or nil
@param key The key for the value
@return The NSArray value or nil
*/
- (NSArray *)arrayForKey:(NSString *)key;
/**
Applies a given block object to the entries of the receiver.
- Parameter block: A block object to operate on entries in the receiver
@param block A block object to operate on entries in the receiver
*/
- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(NSString *key, id object, BOOL *stop))block;
/**
Returns an enumerator object that lets you access each key in the receiver.
- 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;
/**
Gets an NSNumber out of the receiver.
- Parameter key: The key for the value
- Returns: The NSNumber value or nil
@param key The key for the value
@return The NSNumber value or nil
*/
- (NSNumber *)numberForKey:(NSString *)key;
/**
Returns an enumerator object that lets you access each value in the receiver.
- 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;
/**
Gets an FBSDKShareOpenGraphObject out of the receiver.
- Parameter key: The key for the value
- Returns: The FBSDKShareOpenGraphObject value or nil
@param key The key for the value
@return The FBSDKShareOpenGraphObject value or nil
*/
- (FBSDKShareOpenGraphObject *)objectForKey:(NSString *)key;
/**
Enables subscript access to the values in the receiver.
- Parameter key: The key for the value
- Returns: The value
@param key The key for the value
@return The value
*/
- (id)objectForKeyedSubscript:(NSString *)key;
/**
Parses properties out of a dictionary into the receiver.
- Parameter properties: The properties to parse.
@param properties The properties to parse.
*/
- (void)parseProperties:(NSDictionary *)properties;
/**
Gets an FBSDKSharePhoto out of the receiver.
- Parameter key: The key for the value
- Returns: The FBSDKSharePhoto value or nil
@param key The key for the value
@return The FBSDKSharePhoto value or nil
*/
- (FBSDKSharePhoto *)photoForKey:(NSString *)key;
/**
Removes a value from the receiver for the specified key.
- Parameter key: The key for the value
@param key The key for the value
*/
- (void)removeObjectForKey:(NSString *)key;
@@ -98,57 +98,57 @@
This method will throw if the array contains any values that is not an NSNumber, NSString, NSURL,
FBSDKSharePhoto or FBSDKShareOpenGraphObject.
- Parameter array: The NSArray value
- Parameter key: The key for the value
@param array The NSArray value
@param key The key for the value
*/
- (void)setArray:(NSArray *)array forKey:(NSString *)key;
/**
Sets an NSNumber on the receiver.
- Parameter number: The NSNumber value
- Parameter key: The key for the value
@param number The NSNumber value
@param key The key for the value
*/
- (void)setNumber:(NSNumber *)number forKey:(NSString *)key;
/**
Sets an FBSDKShareOpenGraphObject on the receiver.
- Parameter object: The FBSDKShareOpenGraphObject value
- Parameter key: The key for the value
@param object The FBSDKShareOpenGraphObject value
@param key The key for the value
*/
- (void)setObject:(FBSDKShareOpenGraphObject *)object forKey:(NSString *)key;
/**
Sets an FBSDKSharePhoto on the receiver.
- Parameter photo: The FBSDKSharePhoto value
- Parameter key: The key for the value
@param photo The FBSDKSharePhoto value
@param key The key for the value
*/
- (void)setPhoto:(FBSDKSharePhoto *)photo forKey:(NSString *)key;
/**
Sets an NSString on the receiver.
- Parameter string: The NSString value
- Parameter key: The key for the value
@param string The NSString value
@param key The key for the value
*/
- (void)setString:(NSString *)string forKey:(NSString *)key;
/**
Sets an NSURL on the receiver.
- Parameter URL: The NSURL value
- Parameter key: The key for the value
@param URL The NSURL value
@param key The key for the value
*/
- (void)setURL:(NSURL *)URL forKey:(NSString *)key;
/**
Gets an NSString out of the receiver.
- Parameter key: The key for the value
- Returns: The NSString value or nil
@param key The key for the value
@return The NSString value or nil
*/
- (NSString *)stringForKey:(NSString *)key;
/**
Gets an NSURL out of the receiver.
- Parameter key: The key for the value
- Returns: The NSURL value or nil
@param key The key for the value
@return The NSURL value or nil
*/
- (NSURL *)URLForKey:(NSString *)key;
@@ -19,24 +19,27 @@
#import <UIKit/UIKit.h>
#import <FBSDKCoreKit/FBSDKCopying.h>
#import <FBSDKShareKit/FBSDKSharingValidation.h>
@class PHAsset;
/**
A photo for sharing.
*/
@interface FBSDKSharePhoto : NSObject <FBSDKCopying, NSSecureCoding>
@interface FBSDKSharePhoto : NSObject <FBSDKCopying, FBSDKSharingValidation, NSSecureCoding>
/**
Convenience method to build a new photo object with an image.
- Parameter image: If the photo is resident in memory, this method supplies the data
- Parameter userGenerated: Specifies whether the photo represented by the receiver was generated by the user or by the
@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;
/**
Convenience method to build a new photo object with an imageURL.
- Parameter imageURL: The URL to the photo
- Parameter userGenerated: Specifies whether the photo represented by the receiver was generated by the user or by the
@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
This method should only be used when adding photo content to open graph stories.
@@ -45,35 +48,49 @@
*/
+ (instancetype)photoWithImageURL:(NSURL *)imageURL userGenerated:(BOOL)userGenerated;
/**
Convenience method to build a new photo object with a PHAsset.
- Parameter photoAsset: The PHAsset that represents the photo in the Photos library.
- Parameter userGenerated: Specifies whether the photo represented by the receiver was generated by the user or by the
application
*/
+ (instancetype)photoWithPhotoAsset:(PHAsset *)photoAsset userGenerated:(BOOL)userGenerated;
/**
If the photo is resident in memory, this method supplies the data.
- Returns: UIImage representation of the photo
@return UIImage representation of the photo
*/
@property (nonatomic, strong) UIImage *image;
/**
The URL to the photo.
- Returns: URL that points to a network location or the location of the photo on disk
@return URL that points to a network location or the location of the photo on disk
*/
@property (nonatomic, copy) NSURL *imageURL;
/**
The representation of the photo in the Photos library.
- Returns: PHAsset that represents the photo in the Photos library.
*/
@property (nonatomic, copy) PHAsset *photoAsset;
/**
Specifies whether the photo represented by the receiver was generated by the user or by the application.
- Returns: YES if the photo is user-generated, otherwise NO
@return YES if the photo is user-generated, otherwise NO
*/
@property (nonatomic, assign, getter=isUserGenerated) BOOL userGenerated;
/**
Compares the receiver to another photo.
- Parameter photo: The other photo
- Returns: YES if the receiver's values are equal to the other photo's values; otherwise NO
@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;
/**
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).
- Returns: the Photo's caption if exists else returns null.
@return the Photo's caption if exists else returns null.
*/
@property (nonatomic, copy) NSString *caption;
@@ -18,12 +18,16 @@
#import "FBSDKSharePhoto.h"
#import "FBSDKCoreKit+Internal.h"
#import <Photos/Photos.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"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareError.h"
NSString *const kFBSDKSharePhotoAssetKey = @"photoAsset";
NSString *const kFBSDKSharePhotoImageKey = @"image";
NSString *const kFBSDKSharePhotoImageURLKey = @"imageURL";
NSString *const kFBSDKSharePhotoUserGeneratedKey = @"userGenerated";
NSString *const kFBSDKSharePhotoCaptionKey = @"caption";
@implementation FBSDKSharePhoto
@@ -45,6 +49,37 @@
return photo;
}
+ (instancetype)photoWithPhotoAsset:(PHAsset *)photoAsset userGenerated:(BOOL)userGenerated
{
FBSDKSharePhoto *photo = [[self alloc] init];
photo.photoAsset = photoAsset;
photo.userGenerated = userGenerated;
return photo;
}
#pragma mark - Properties
- (void)setImage:(UIImage *)image
{
_image = image;
_imageURL = nil;
_photoAsset = nil;
}
- (void)setImageURL:(NSURL *)imageURL
{
_image = nil;
_imageURL = [imageURL copy];
_photoAsset = nil;
}
- (void)setPhotoAsset:(PHAsset *)photoAsset
{
_image = nil;
_imageURL = nil;
_photoAsset = [photoAsset copy];
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -52,6 +87,7 @@
NSUInteger subhashes[] = {
[_image hash],
[_imageURL hash],
[_photoAsset hash],
[_caption hash],
(_userGenerated ? 1u : 0u)
};
@@ -75,9 +111,72 @@
(_userGenerated == photo.userGenerated) &&
[FBSDKInternalUtility object:_image isEqualToObject:photo.image] &&
[FBSDKInternalUtility object:_imageURL isEqualToObject:photo.imageURL] &&
[FBSDKInternalUtility object:_photoAsset isEqualToObject:photo.photoAsset] &&
[FBSDKInternalUtility object:_caption isEqualToObject:photo.caption]);
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
if (bridgeOptions & FBSDKShareBridgeOptionsPhotoImageURL) { // a web-based URL is required
if (_imageURL) {
if (_imageURL.isFileURL) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"imageURL"
value:_imageURL
message:@"Cannot refer to a local file resource."];
}
return NO;
} else {
return YES; // will bridge the image URL
}
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"photo"
value:self
message:@"imageURL is required."];
}
return NO;
}
} else if (_photoAsset) {
if (PHAssetMediaTypeImage == _photoAsset.mediaType) {
if (bridgeOptions & FBSDKShareBridgeOptionsPhotoAsset) {
return YES; // will bridge the PHAsset.localIdentifier
} else {
return YES; // will load the asset and bridge the image
}
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"photoAsset"
value:_photoAsset
message:@"Must refer to a photo or other static image."];
}
return NO;
}
} else if (_imageURL) {
if (_imageURL.isFileURL) {
return YES; // will load the contents of the file and bridge the image
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"imageURL"
value:_imageURL
message:@"Must refer to a local file resource."];
}
return NO;
}
} else if (_image) {
return YES; // will bridge the image
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"photo"
value:self
message:@"Must have an asset, image, or imageURL value."];
}
return NO;
}
}
#pragma mark - NSCoding
+ (BOOL)supportsSecureCoding
@@ -88,20 +187,25 @@
- (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];
_image = [decoder decodeObjectOfClass:[UIImage class] forKey:kFBSDKSharePhotoImageKey];
_imageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:kFBSDKSharePhotoImageURLKey];
NSString *localIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKSharePhotoAssetKey];
if (localIdentifier && (PHAuthorizationStatusAuthorized == [PHPhotoLibrary authorizationStatus])) {
_photoAsset = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil].firstObject;
}
_userGenerated = [decoder decodeBoolForKey:kFBSDKSharePhotoUserGeneratedKey];
_caption = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKSharePhotoCaptionKey];
}
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];
[encoder encodeObject:_image forKey:kFBSDKSharePhotoImageKey];
[encoder encodeObject:_imageURL forKey:kFBSDKSharePhotoImageURLKey];
[encoder encodeObject:_photoAsset.localIdentifier forKey:kFBSDKSharePhotoAssetKey];
[encoder encodeBool:_userGenerated forKey:kFBSDKSharePhotoUserGeneratedKey];
[encoder encodeObject:_caption forKey:kFBSDKSharePhotoCaptionKey];
}
#pragma mark - NSCopying
@@ -111,6 +215,7 @@
FBSDKSharePhoto *copy = [[FBSDKSharePhoto alloc] init];
copy->_image = [_image copy];
copy->_imageURL = [_imageURL copy];
copy->_photoAsset = [_photoAsset copy];
copy->_userGenerated = _userGenerated;
copy->_caption = [_caption copy];
return copy;
@@ -27,14 +27,14 @@
/**
Photos to be shared.
- Returns: Array of the photos (FBSDKSharePhoto)
@return Array of the photos (FBSDKSharePhoto)
*/
@property (nonatomic, copy) NSArray *photos;
/**
Compares the receiver to another photo content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@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;
@@ -18,8 +18,11 @@
#import "FBSDKSharePhotoContent.h"
#import <Photos/Photos.h>
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKHashtag.h"
#import "FBSDKShareError.h"
#import "FBSDKSharePhoto.h"
#import "FBSDKShareUtility.h"
@@ -73,6 +76,64 @@
}
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
NSMutableArray<UIImage *> *images = [[NSMutableArray alloc] init];
for (FBSDKSharePhoto *photo in _photos) {
if (photo.photoAsset) {
// load the asset and bridge the image
PHImageRequestOptions *imageRequestOptions = [[PHImageRequestOptions alloc] init];
imageRequestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
imageRequestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
imageRequestOptions.synchronous = YES;
[[PHImageManager defaultManager]
requestImageForAsset:photo.photoAsset
targetSize:PHImageManagerMaximumSize
contentMode:PHImageContentModeDefault
options:imageRequestOptions
resultHandler:^(UIImage *image, NSDictionary<NSString *, id> *info) {
if (image) {
[images addObject:image];
}
}];
} else if (photo.imageURL) {
if (photo.imageURL.isFileURL) {
// load the contents of the file and bridge the image
UIImage *image = [UIImage imageWithContentsOfFile:[photo.imageURL absoluteString]];
if (image) {
[images addObject:photo.image];
}
}
} else if (photo.image) {
// bridge the image
[images addObject:photo.image];
}
}
if (images.count > 0) {
[FBSDKInternalUtility dictionary:parameters
setObject:images
forKey:@"photos"];
}
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
if (![FBSDKShareUtility validateArray:_photos minCount:1 maxCount:6 name:@"photos" error:errorRef]) {
return NO;
}
for (FBSDKSharePhoto *photo in _photos) {
if (![photo validateWithOptions:bridgeOptions error:errorRef]) {
return NO;
}
}
return YES;
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -19,43 +19,83 @@
#import <UIKit/UIKit.h>
#import <FBSDKCoreKit/FBSDKCopying.h>
#import <FBSDKShareKit/FBSDKSharingValidation.h>
@class FBSDKSharePhoto;
@class PHAsset;
/**
A video for sharing.
*/
@interface FBSDKShareVideo : NSObject <FBSDKCopying, NSSecureCoding>
@interface FBSDKShareVideo : NSObject <FBSDKCopying, FBSDKSharingValidation, NSSecureCoding>
/**
Convenience method to build a new video object from raw data.
- Parameter data: The NSData object that holds the raw video data.
*/
+ (instancetype)videoWithData:(NSData *)data;
/**
Convenience method to build a new video object with NSData and a previewPhoto.
- Parameter data: The NSData object that holds the raw video data.
- Parameter previewPhoto: The photo that represents the video.
*/
+ (instancetype)videoWithData:(NSData *)data previewPhoto:(FBSDKSharePhoto *)previewPhoto;
/**
Convenience method to build a new video object with a PHAsset.
@param videoAsset The PHAsset that represents the video in the Photos library.
*/
+ (instancetype)videoWithVideoAsset:(PHAsset *)videoAsset;
/**
Convenience method to build a new video object with a PHAsset and a previewPhoto.
@param videoAsset The PHAsset that represents the video in the Photos library.
@param previewPhoto The photo that represents the video.
*/
+ (instancetype)videoWithVideoAsset:(PHAsset *)videoAsset previewPhoto:(FBSDKSharePhoto *)previewPhoto;
/**
Convenience method to build a new video object with a videoURL.
- Parameter videoURL: The URL to the video
@param videoURL The URL to the video.
*/
+ (instancetype)videoWithVideoURL:(NSURL *)videoURL;
/**
Convenience method to build a new video object with a videoURL and a previewPhoto
- Parameter videoURL: The URL to the video
- Parameter previewPhoto: The photo that represents the video
Convenience method to build a new video object with a videoURL and a previewPhoto.
@param videoURL The URL to the video.
@param previewPhoto The photo that represents the video.
*/
+ (instancetype)videoWithVideoURL:(NSURL *)videoURL previewPhoto:(FBSDKSharePhoto *)previewPhoto;
/**
The raw video data.
- Returns: The video data.
*/
@property (nonatomic, strong) NSData *data;
/**
The representation of the video in the Photos library.
@return PHAsset that represents the video in the Photos library.
*/
@property (nonatomic, copy) PHAsset *videoAsset;
/**
The file URL to the video.
- Returns: URL that points to the location of the video on disk
@return URL that points to the location of the video on disk
*/
@property (nonatomic, copy) NSURL *videoURL;
/**
The photo that represents the video.
- Returns: The photo
@return The photo
*/
@property (nonatomic, copy) FBSDKSharePhoto *previewPhoto;
/**
Compares the receiver to another video.
- Parameter video: The other video
- Returns: YES if the receiver's values are equal to the other video's values; otherwise NO
@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;
@@ -18,16 +18,52 @@
#import "FBSDKShareVideo.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKSharePhoto.h"
#import <Photos/Photos.h>
#define FBSDK_SHARE_VIDEO_URL_KEY @"videoURL"
#define FBSDK_SHARE_VIDEO_PREVIEW_PHOTO_KEY @"previewPhoto"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareError.h"
#import "FBSDKSharePhoto.h"
#import "FBSDKShareUtility.h"
NSString *const kFBSDKShareVideoAssetKey = @"videoAsset";
NSString *const kFBSDKShareVideoDataKey = @"data";
NSString *const kFBSDKShareVideoPreviewPhotoKey = @"previewPhoto";
NSString *const kFBSDKShareVideoURLKey = @"videoURL";
@implementation FBSDKShareVideo
#pragma mark - Class Methods
+ (instancetype)videoWithData:(NSData *)data
{
FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init];
video.data = data;
return video;
}
+ (instancetype)videoWithData:(NSData *)data previewPhoto:(FBSDKSharePhoto *)previewPhoto
{
FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init];
video.data = data;
video.previewPhoto = previewPhoto;
return video;
}
+ (instancetype)videoWithVideoAsset:(PHAsset *)videoAsset
{
FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init];
video.videoAsset = videoAsset;
return video;
}
+ (instancetype)videoWithVideoAsset:(PHAsset *)videoAsset previewPhoto:(FBSDKSharePhoto *)previewPhoto
{
FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init];
video.videoAsset = videoAsset;
video.previewPhoto = previewPhoto;
return video;
}
+ (instancetype)videoWithVideoURL:(NSURL *)videoURL
{
FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init];
@@ -43,11 +79,39 @@
return video;
}
#pragma mark - Properties
- (void)setData:(NSData *)data
{
_data = data;
_videoAsset = nil;
_videoURL = nil;
_previewPhoto = nil;
}
- (void)setVideoAsset:(PHAsset *)videoAsset
{
_data = nil;
_videoAsset = [videoAsset copy];
_videoURL = nil;
_previewPhoto = nil;
}
- (void)setVideoURL:(NSURL *)videoURL
{
_data = nil;
_videoAsset = nil;
_videoURL = [videoURL copy];
_previewPhoto = nil;
}
#pragma mark - Equality
- (NSUInteger)hash
{
NSUInteger subhashes[] = {
[_data hash],
[_videoAsset hash],
[_videoURL hash],
[_previewPhoto hash],
};
@@ -68,10 +132,95 @@
- (BOOL)isEqualToShareVideo:(FBSDKShareVideo *)video
{
return (video &&
[FBSDKInternalUtility object:_data isEqualToObject:video.data] &&
[FBSDKInternalUtility object:_videoAsset isEqualToObject:video.videoAsset] &&
[FBSDKInternalUtility object:_videoURL isEqualToObject:video.videoURL] &&
[FBSDKInternalUtility object:_previewPhoto isEqualToObject:video.previewPhoto]);
}
#pragma mark - FBSDKSharingValidation
- (BOOL)_validateData:(NSData *)data
withOptions:(FBSDKShareBridgeOptions)bridgeOptions
error:(NSError *__autoreleasing *)errorRef
{
if (data) {
if (bridgeOptions & FBSDKShareBridgeOptionsVideoData) {
return YES; // will bridge the data
}
}
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"data"
value:data
message:@"Cannot share video data."];
}
return NO;
}
- (BOOL)_validateVideoAsset:(PHAsset *)videoAsset
withOptions:(FBSDKShareBridgeOptions)bridgeOptions
error:(NSError *__autoreleasing *)errorRef
{
if (videoAsset) {
if (PHAssetMediaTypeVideo == videoAsset.mediaType) {
if (bridgeOptions & FBSDKShareBridgeOptionsVideoAsset) {
return YES; // will bridge the PHAsset.localIdentifier
} else {
return YES; // will bridge the legacy "assets-library" URL from AVAsset
}
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"videoAsset"
value:videoAsset
message:@"Must refer to a video file."];
}
return NO;
}
}
return NO;
}
- (BOOL)_validateVideoURL:(NSURL *)videoURL
withOptions:(FBSDKShareBridgeOptions)bridgeOptions
error:(NSError *__autoreleasing *)errorRef
{
if (videoURL) {
if ([[videoURL.scheme lowercaseString] isEqualToString:@"assets-library"]) {
return YES; // will bridge the legacy "assets-library" URL
} else if (videoURL.isFileURL) {
if (bridgeOptions & FBSDKShareBridgeOptionsVideoData) {
return YES; // will load the contents of the file and bridge the data
}
}
}
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"videoURL"
value:videoURL
message:@"Must refer to an asset file."];
}
return NO;
}
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
// validate that a valid asset, data, or videoURL value has been set.
// don't validate the preview photo; if it isn't valid it'll be dropped from the share; a default one may be created if needed.
if (_videoAsset) {
return [self _validateVideoAsset:_videoAsset withOptions:bridgeOptions error:errorRef];
} else if (_data) {
return [self _validateData:_data withOptions:bridgeOptions error:errorRef];
} else if (_videoURL) {
return [self _validateVideoURL:_videoURL withOptions:bridgeOptions error:errorRef];
} else {
if ((errorRef != NULL) && !*errorRef) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"video"
value:self
message:@"Must have an asset, data, or videoURL value."];
}
return NO;
}
}
#pragma mark - NSCoding
+ (BOOL)supportsSecureCoding
@@ -82,16 +231,23 @@
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [self init])) {
_videoURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_VIDEO_URL_KEY];
_previewPhoto = [decoder decodeObjectOfClass:[FBSDKSharePhoto class] forKey:FBSDK_SHARE_VIDEO_PREVIEW_PHOTO_KEY];
_data = [decoder decodeObjectOfClass:[NSData class] forKey:kFBSDKShareVideoDataKey];
NSString *localIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:kFBSDKShareVideoAssetKey];
if (localIdentifier && (PHAuthorizationStatusAuthorized == [PHPhotoLibrary authorizationStatus])) {
_videoAsset = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil].firstObject;
}
_videoURL = [decoder decodeObjectOfClass:[NSURL class] forKey:kFBSDKShareVideoURLKey];
_previewPhoto = [decoder decodeObjectOfClass:[FBSDKSharePhoto class] forKey:kFBSDKShareVideoPreviewPhotoKey];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:_videoURL forKey:FBSDK_SHARE_VIDEO_URL_KEY];
[encoder encodeObject:_previewPhoto forKey:FBSDK_SHARE_VIDEO_PREVIEW_PHOTO_KEY];
[encoder encodeObject:_data forKey:kFBSDKShareVideoDataKey];
[encoder encodeObject:_videoAsset.localIdentifier forKey:kFBSDKShareVideoAssetKey];
[encoder encodeObject:_videoURL forKey:kFBSDKShareVideoURLKey];
[encoder encodeObject:_previewPhoto forKey:kFBSDKShareVideoPreviewPhotoKey];
}
#pragma mark - NSCopying
@@ -99,6 +255,8 @@
- (id)copyWithZone:(NSZone *)zone
{
FBSDKShareVideo *copy = [[FBSDKShareVideo alloc] init];
copy->_data = [_data copy];
copy->_videoAsset = [_videoAsset copy];
copy->_videoURL = [_videoURL copy];
copy->_previewPhoto = [_previewPhoto copy];
return copy;
@@ -29,20 +29,21 @@
/**
The photo that represents the video.
- Returns: The photo
@return The photo
*/
@property (nonatomic, copy) FBSDKSharePhoto *previewPhoto;
@property (nonatomic, copy) FBSDKSharePhoto *previewPhoto
DEPRECATED_MSG_ATTRIBUTE("Use `video.previewPhoto`");
/**
The video to be shared.
- Returns: The video
@return The video
*/
@property (nonatomic, copy) FBSDKShareVideo *video;
/**
Compares the receiver to another video content.
- Parameter content: The other content
- Returns: YES if the receiver's values are equal to the other content's values; otherwise NO
@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;
@@ -18,6 +18,8 @@
#import "FBSDKShareVideoContent.h"
#import <Photos/Photos.h>
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKHashtag.h"
#import "FBSDKShareUtility.h"
@@ -65,6 +67,85 @@
}
}
#pragma mark - FBSDKSharingContent
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
{
NSMutableDictionary<NSString *, id> *videoParameters = [[NSMutableDictionary alloc] init];
if (_video.videoAsset) {
if (bridgeOptions & FBSDKShareBridgeOptionsVideoAsset) {
// bridge the PHAsset.localIdentifier
[FBSDKInternalUtility dictionary:videoParameters
setObject:_video.videoAsset.localIdentifier
forKey:@"assetIdentifier"];
} else {
// bridge the legacy "assets-library" URL from AVAsset
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionCurrent;
options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
options.networkAccessAllowed = YES;
[[PHImageManager defaultManager] requestAVAssetForVideo:_video.videoAsset
options:options
resultHandler:^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary<NSString *, id> *info) {
NSURL *filePathURL = [[(AVURLAsset *)avAsset URL] filePathURL];
NSString *pathExtension = [filePathURL pathExtension];
NSString *localIdentifier = [self->_video.videoAsset localIdentifier];
NSRange range = [localIdentifier rangeOfString:@"/"];
NSString *uuid = [localIdentifier substringToIndex:range.location];
NSString *assetPath = [NSString stringWithFormat:@"assets-library://asset/asset.%@?id=%@&ext=%@", pathExtension, uuid, pathExtension];
if (assetPath) {
[FBSDKInternalUtility dictionary:videoParameters
setObject:[NSURL URLWithString:assetPath]
forKey:@"assetURL"];
}
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 500 * NSEC_PER_MSEC));
}
} else if (_video.data) {
if (bridgeOptions & FBSDKShareBridgeOptionsVideoData) {
// bridge the data
[FBSDKInternalUtility dictionary:videoParameters
setObject:_video.data
forKey:@"data"];
}
} else if (_video.videoURL) {
if ([[_video.videoURL.scheme lowercaseString] isEqualToString:@"assets-library"]) {
// bridge the legacy "assets-library" URL
[FBSDKInternalUtility dictionary:videoParameters
setObject:_video.videoURL
forKey:@"assetURL"];
} else if (_video.videoURL.isFileURL) {
if (bridgeOptions & FBSDKShareBridgeOptionsVideoData) {
// load the contents of the file and bridge the data
NSData *data = [NSData dataWithContentsOfURL:_video.videoURL options:NSDataReadingMappedIfSafe error:NULL];
[FBSDKInternalUtility dictionary:videoParameters
setObject:data
forKey:@"data"];
}
}
}
[FBSDKInternalUtility dictionary:videoParameters
setObject:[FBSDKShareUtility convertPhoto:_previewPhoto]
forKey:@"previewPhoto"];
[FBSDKInternalUtility dictionary:parameters
setObject:videoParameters
forKey:@"video"];
}
#pragma mark - FBSDKSharingValidation
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef
{
if (![FBSDKShareUtility validateRequiredValue:_video name:@"video" error:errorRef]) {
return NO;
}
return [_video validateWithOptions:bridgeOptions error:errorRef];
}
#pragma mark - Equality
- (NSUInteger)hash
@@ -101,7 +182,10 @@
[FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] &&
[FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] &&
[FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] &&
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[FBSDKInternalUtility object:_previewPhoto isEqualToObject:content.previewPhoto] &&
#pragma clang diagnostic pop
[FBSDKInternalUtility object:_ref isEqualToObject:content.ref] &&
[FBSDKInternalUtility object:_pageID isEqualToObject:content.pageID] &&
[FBSDKInternalUtility object:_shareUUID isEqualToObject:content.shareUUID] &&
@@ -25,11 +25,11 @@
/**
The common interface for components that initiate sharing.
- See:FBSDKShareDialog
@see FBSDKShareDialog
- See:FBSDKMessageDialog
@see FBSDKMessageDialog
- See:FBSDKShareAPI
@see FBSDKShareAPI
*/
@protocol FBSDKSharing <NSObject>
@@ -53,8 +53,8 @@
/**
Validates the content on the receiver.
- Parameter errorRef: If an error occurs, upon return contains an NSError object that describes the problem.
- Returns: YES if the content is valid, otherwise NO.
@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;
@@ -72,14 +72,14 @@
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:]
- Returns: YES if the receiver can share, otherwise NO.
@see [FBSDKSharing validateWithError:]
@return YES if the receiver can share, otherwise NO.
*/
- (BOOL)canShow;
/**
Shows the dialog.
- Returns: YES if the receiver was able to begin sharing, otherwise NO.
@return YES if the receiver was able to begin sharing, otherwise NO.
*/
- (BOOL)show;
@@ -96,21 +96,21 @@
/**
Sent to the delegate when the share completes without error or cancellation.
- Parameter sharer: The FBSDKSharing that completed.
- Parameter results: The results from the sharer. This may be nil or empty.
@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;
/**
Sent to the delegate when the sharer encounters an error.
- Parameter sharer: The FBSDKSharing that completed.
- Parameter error: The error.
@param sharer The FBSDKSharing that completed.
@param error The error.
*/
- (void)sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error;
/**
Sent to the delegate when the sharer is cancelled.
- Parameter sharer: The FBSDKSharing that completed.
@param sharer The FBSDKSharing that completed.
*/
- (void)sharerDidCancel:(id<FBSDKSharing>)sharer;
@@ -23,9 +23,9 @@
/**
The common interface for sharing buttons.
- See:FBSDKSendButton
@see FBSDKSendButton
- See:FBSDKShareButton
@see FBSDKShareButton
*/
@protocol FBSDKSharingButton <NSObject>
@@ -19,26 +19,27 @@
#import <Foundation/Foundation.h>
#import <FBSDKCoreKit/FBSDKCopying.h>
#import <FBSDKShareKit/FBSDKSharingValidation.h>
@class FBSDKHashtag;
/**
A base interface for content to be shared.
*/
@protocol FBSDKSharingContent <FBSDKCopying, NSSecureCoding>
@protocol FBSDKSharingContent <FBSDKCopying, FBSDKSharingValidation, NSSecureCoding>
/**
URL for the content being shared.
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/)
- Returns: URL representation of the content link
@return URL representation of the content link
*/
@property (nonatomic, copy) NSURL *contentURL;
/**
Hashtag for the content being shared.
- Returns: The hashtag for the content being shared.
@return The hashtag for the content being shared.
*/
@property (nonatomic, copy) FBSDKHashtag *hashtag;
@@ -46,32 +47,39 @@
List of IDs for taggable people to tag with this content.
See documentation for Taggable Friends
(https://developers.facebook.com/docs/graph-api/reference/user/taggable_friends)
- Returns: Array of IDs for people to tag (NSString)
@return Array of IDs for people to tag (NSString)
*/
@property (nonatomic, copy) NSArray *peopleIDs;
/**
The ID for a place to tag with this content.
- Returns: The ID for the place to tag
@return The ID for the place to tag
*/
@property (nonatomic, copy) NSString *placeID;
/**
A value to be added to the referrer URL when a person follows a link from this shared content on feed.
- Returns: The ref for the content.
@return The ref for the content.
*/
@property (nonatomic, copy) NSString *ref;
/**
For shares into Messenger, this pageID will be used to map the app to page and attach attribution to the share.
- Returns: The ID of the Facebok page this share is associated with.
@return The ID of the Facebok page this share is associated with.
*/
@property (nonatomic, copy) NSString *pageID;
/**
A unique identifier for a share involving this content, useful for tracking purposes.
- Returns: A unique string identifying this share data.
@return A unique string identifying this share data.
*/
@property (nonatomic, copy, readonly) NSString *shareUUID;
/**
Adds content to a dictionary as key/value pairs.
- Parameter parameters: A mutable dictionary that may be appended with key/value pairs of content.
*/
- (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions;
@end
@@ -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 "FBSDKShareDialogMode.h"
/**
A base interface for indicating a custom URL scheme
*/
@protocol FBSDKSharingScheme
/**
Asks the receiver to provide a custom scheme.
- Parameter mode: The intended dialog mode for sharing the content.
- Returns: A custom URL scheme to use for the specified mode, or nil.
*/
- (nullable NSString *)schemeForMode:(FBSDKShareDialogMode)mode;
@end
@@ -0,0 +1,46 @@
// 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>
/**
Flags to indicate support for newer bridge options beyond the initial 20130410 implementation.
*/
typedef NS_OPTIONS(NSUInteger, FBSDKShareBridgeOptions)
{
FBSDKShareBridgeOptionsDefault = 0,
FBSDKShareBridgeOptionsPhotoAsset = 1 << 0,
FBSDKShareBridgeOptionsPhotoImageURL = 1 << 1, // if set, a web-based URL is required; asset, image, and imageURL.isFileURL not allowed
FBSDKShareBridgeOptionsVideoAsset = 1 << 2,
FBSDKShareBridgeOptionsVideoData = 1 << 3,
FBSDKShareBridgeOptionsWebHashtag = 1 << 4, // if set, pass the hashtag as a string value, not an array of one string
};
/**
A base interface for validation of content and media.
*/
@protocol FBSDKSharingValidation
/**
Asks the receiver to validate that its content or media values are valid.
- Parameter errorRef: Optional, will receive an FBSDKShareError if the values are not valid.
- Returns: YES if the receiver's values are valid; otherwise NO
*/
- (BOOL)validateWithOptions:(FBSDKShareBridgeOptions)bridgeOptions error:(NSError *__autoreleasing *)errorRef;
@end
@@ -93,7 +93,7 @@
if (!error) {
NSArray *items = [FBSDKTypeUtility arrayValue:result[@"data"]];
NSArray *recipientIDs = [items valueForKey:@"recipient_id"];
_recipientIDs = [[NSSet alloc] initWithArray:recipientIDs];
self->_recipientIDs = [[NSSet alloc] initWithArray:recipientIDs];
}
}];
}
@@ -758,8 +758,8 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
NSString *innerVerifiedObjectID,
BOOL innerObjectIsPage) {
if (success) {
_verifiedObjectID = [innerVerifiedObjectID copy];
_objectIsPage = innerObjectIsPage;
self->_verifiedObjectID = [innerVerifiedObjectID copy];
self->_objectIsPage = innerObjectIsPage;
}
});
}
@@ -770,13 +770,13 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
if (success) {
// if this was an URL based request, then we want to use the objectID from that request - this value will just
// be an echo of the URL
if (!_verifiedObjectID) {
_verifiedObjectID = [innerVerifiedObjectID copy];
if (!self->_verifiedObjectID) {
self->_verifiedObjectID = [innerVerifiedObjectID copy];
}
_objectIsPage = innerObjectIsPage;
self->_objectIsPage = innerObjectIsPage;
}
if (_verifiedObjectID) {
completion(_verifiedObjectID);
if (self->_verifiedObjectID) {
completion(self->_verifiedObjectID);
}
});
[connection start];
@@ -826,21 +826,21 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
[connection overrideVersionPartWith:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION];
fbsdk_like_action_controller_publish_like_completion_block completionHandler = ^(BOOL success,
NSString *unlikeToken) {
_objectIsLikedIsPending = NO;
self->_objectIsLikedIsPending = NO;
if (success) {
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKLikeControlDidLike
valueToSum:nil
parameters:analyticsParameters
accessToken:_accessToken];
_objectIsLikedOnServer = YES;
_unlikeToken = [unlikeToken copy];
accessToken:self->_accessToken];
self->_objectIsLikedOnServer = YES;
self->_unlikeToken = [unlikeToken copy];
if (updateBlock != NULL) {
updateBlock(FBSDKTriStateBOOLFromBOOL(self.objectIsLiked),
_likeCountStringWithLike,
_likeCountStringWithoutLike,
_socialSentenceWithLike,
_socialSentenceWithoutLike,
_unlikeToken,
self->_likeCountStringWithLike,
self->_likeCountStringWithoutLike,
self->_socialSentenceWithLike,
self->_socialSentenceWithoutLike,
self->_unlikeToken,
NO,
NO);
}
@@ -849,10 +849,10 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
[self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController];
}
};
FBSDKLikeActionControllerAddPublishLikeRequest(_accessToken,
FBSDKLikeActionControllerAddPublishLikeRequest(self->_accessToken,
connection,
verifiedObjectID,
_objectType,
self->_objectType,
completionHandler);
[connection start];
}];
@@ -866,21 +866,21 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
[connection overrideVersionPartWith:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION];
fbsdk_like_action_controller_publish_unlike_completion_block completionHandler = ^(BOOL success) {
_objectIsLikedIsPending = NO;
self->_objectIsLikedIsPending = NO;
if (success) {
[FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKLikeControlDidUnlike
valueToSum:nil
parameters:analyticsParameters
accessToken:_accessToken];
_objectIsLikedOnServer = NO;
_unlikeToken = nil;
accessToken:self->_accessToken];
self->_objectIsLikedOnServer = NO;
self->_unlikeToken = nil;
if (updateBlock != NULL) {
updateBlock(FBSDKTriStateBOOLFromBOOL(self.objectIsLiked),
_likeCountStringWithLike,
_likeCountStringWithoutLike,
_socialSentenceWithLike,
_socialSentenceWithoutLike,
_unlikeToken,
self->_likeCountStringWithLike,
self->_likeCountStringWithoutLike,
self->_socialSentenceWithLike,
self->_socialSentenceWithoutLike,
self->_unlikeToken,
NO,
NO);
}
@@ -927,10 +927,10 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
[self _ensureVerifiedObjectID:^(NSString *verifiedObjectID) {
FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init];
[connection overrideVersionPartWith:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION];
FBSDKLikeActionControllerAddRefreshRequests(_accessToken,
FBSDKLikeActionControllerAddRefreshRequests(self->_accessToken,
connection,
verifiedObjectID,
_objectType,
self->_objectType,
^(FBSDKTriStateBOOL objectIsLiked,
NSString *likeCountStringWithLike,
NSString *likeCountStringWithoutLike,
@@ -949,7 +949,7 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
animated:NO
deferred:NO];
[self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY];
_refreshState = FBSDKLikeActionControllerRefreshStateComplete;
self->_refreshState = FBSDKLikeActionControllerRefreshStateComplete;
});
[connection start];
}];
@@ -1010,23 +1010,23 @@ static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *access
void(^updateBlock)(void) = ^{
if (objectIsLikedChanged) {
_objectIsLiked = objectIsLiked;
self->_objectIsLiked = objectIsLiked;
}
if (likeCountStringWithLike) {
_likeCountStringWithLike = [likeCountStringWithLike copy];
self->_likeCountStringWithLike = [likeCountStringWithLike copy];
}
if (likeCountStringWithoutLike) {
_likeCountStringWithoutLike = [likeCountStringWithoutLike copy];
self->_likeCountStringWithoutLike = [likeCountStringWithoutLike copy];
}
if (socialSentenceWithLike) {
_socialSentenceWithLike = [socialSentenceWithLike copy];
self->_socialSentenceWithLike = [socialSentenceWithLike copy];
}
if (socialSentenceWithoutLike) {
_socialSentenceWithoutLike = [socialSentenceWithoutLike copy];
self->_socialSentenceWithoutLike = [socialSentenceWithoutLike copy];
}
if (unlikeToken) {
_unlikeToken = [unlikeToken copy];
self->_unlikeToken = [unlikeToken copy];
}
// if only meta data changed, don't play the sound
@@ -18,19 +18,32 @@
#import <Foundation/Foundation.h>
@class FBSDKShareMessengerGenericTemplateContent;
@class FBSDKShareMessengerMediaTemplateContent;
@class FBSDKShareMessengerOpenGraphMusicTemplateContent;
@class FBSDKShareMessengerURLActionButton;
@protocol FBSDKShareMessengerActionButton;
extern NSString *const kFBSDKShareMessengerTemplateTypeKey;
extern NSString *const kFBSDKShareMessengerTemplateKey;
extern NSString *const kFBSDKShareMessengerPayloadKey;
extern NSString *const kFBSDKShareMessengerTypeKey;
extern NSString *const kFBSDKShareMessengerAttachmentKey;
extern NSString *const kFBSDKShareMessengerElementsKey;
extern NSString *const kFBSDKShareMessengerButtonsKey;
void AddToContentPreviewDictionaryForButton(NSMutableDictionary<NSString *, id> *dictionary,
id<FBSDKShareMessengerActionButton> button);
NSDictionary<NSString *, id> *SerializableButtonFromURLButton(FBSDKShareMessengerURLActionButton *button, BOOL isDefaultAction);
NSArray<NSDictionary<NSString *, id> *> *SerializableButtonsFromButton(id<FBSDKShareMessengerActionButton> button);
@interface FBSDKShareMessengerContentUtility : NSObject
+ (void)addToParameters:(NSMutableDictionary *)parameters
forShareMessengerGenericTemplateContent:(FBSDKShareMessengerGenericTemplateContent *)genericTemplateContent;
+ (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
contentForShare:(NSMutableDictionary<NSString *, id> *)contentForShare
contentForPreview:(NSMutableDictionary<NSString *, id> *)contentForPreview;
+ (void)addToParameters:(NSMutableDictionary *)parameters
forShareMessengerMediaTemplateContent:(FBSDKShareMessengerMediaTemplateContent *)mediaTemplateContent;
+ (void)addToParameters:(NSMutableDictionary *)parameters
forShareMessengerOpenGraphMusicTemplateContent:(FBSDKShareMessengerOpenGraphMusicTemplateContent *)openGraphMusicTemplate;
+ (BOOL)validateMessengerActionButton:(id<FBSDKShareMessengerActionButton>)button
isDefaultActionButton:(BOOL)isDefaultActionButton
pageID:(NSString *)pageID
error:(NSError *__autoreleasing *)errorRef;
@end
@@ -19,39 +19,23 @@
#import "FBSDKShareMessengerContentUtility.h"
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareError.h"
#import "FBSDKShareMessengerGenericTemplateContent.h"
#import "FBSDKShareMessengerGenericTemplateElement.h"
#import "FBSDKShareMessengerMediaTemplateContent.h"
#import "FBSDKShareMessengerOpenGraphMusicTemplateContent.h"
#import "FBSDKShareMessengerURLActionButton.h"
#import "FBSDKShareUtility.h"
static NSString *const kTemplateTypeKey = @"template_type";
static NSString *const kTemplateKey = @"template";
static NSString *const kPayloadKey = @"payload";
static NSString *const kTypeKey = @"type";
static NSString *const kAttachmentKey = @"attachment";
static NSString *const kElementsKey = @"elements";
static NSString *const kButtonsKey = @"buttons";
NSString *const kFBSDKShareMessengerTemplateTypeKey = @"template_type";
NSString *const kFBSDKShareMessengerTemplateKey = @"template";
NSString *const kFBSDKShareMessengerPayloadKey = @"payload";
NSString *const kFBSDKShareMessengerTypeKey = @"type";
NSString *const kFBSDKShareMessengerAttachmentKey = @"attachment";
NSString *const kFBSDKShareMessengerElementsKey = @"elements";
NSString *const kFBSDKShareMessengerButtonsKey = @"buttons";
@implementation FBSDKShareMessengerContentUtility
static BOOL _URLHasFacebookDomain(NSURL *URL)
{
NSString *urlHost = [URL.host lowercaseString];
NSArray<NSString *> *pathComponents = [URL pathComponents];
/**
Check the following three different cases...
1. Check if host is facebook.com, such as in 'https://facebok.com/test'
2. Check if host is someprefix.facebook.com, such as in 'https://www.facebook.com/test'
3. Check if host is null, but the first path component is facebook.com
*/
return [urlHost isEqualToString:@"facebook.com"] ||
[urlHost hasSuffix:@".facebook.com"] ||
([[[pathComponents firstObject] lowercaseString] hasSuffix:@"facebook.com"]);
}
static void _AddToContentPreviewDictionaryForURLButton(NSMutableDictionary *dictionary,
static void _AddToContentPreviewDictionaryForURLButton(NSMutableDictionary<NSString *, id> *dictionary,
FBSDKShareMessengerURLActionButton *urlButton)
{
NSString *urlString = urlButton.url.absoluteString;
@@ -67,14 +51,16 @@ static void _AddToContentPreviewDictionaryForURLButton(NSMutableDictionary *dict
[FBSDKInternalUtility dictionary:dictionary setObject:urlButton.url.absoluteString forKey:@"item_url"];
}
static void _AddToContentPreviewDictionaryForButton(NSMutableDictionary *dictionary,
id<FBSDKShareMessengerActionButton> button)
void AddToContentPreviewDictionaryForButton(NSMutableDictionary<NSString *, id> *dictionary,
id<FBSDKShareMessengerActionButton> button)
{
if ([button isKindOfClass:[FBSDKShareMessengerURLActionButton class]]) {
_AddToContentPreviewDictionaryForURLButton(dictionary, button);
}
}
@implementation FBSDKShareMessengerContentUtility
static NSString *_WebviewHeightRatioString(FBSDKShareMessengerURLActionButtonWebviewHeightRatio heightRatio) {
switch (heightRatio) {
case FBSDKShareMessengerURLActionButtonWebviewHeightRatioFull:
@@ -86,31 +72,11 @@ static NSString *_WebviewHeightRatioString(FBSDKShareMessengerURLActionButtonWeb
}
}
static NSString *_MediaTypeString(FBSDKShareMessengerMediaTemplateMediaType mediaType)
{
switch (mediaType) {
case FBSDKShareMessengerMediaTemplateMediaTypeImage:
return @"image";
case FBSDKShareMessengerMediaTemplateMediaTypeVideo:
return @"video";
}
}
static NSString *_WebviewShareButtonString(BOOL shouldHideWebviewShareButton) {
return shouldHideWebviewShareButton ? @"hide" : nil;
}
static NSString *_ImageAspectRatioString(FBSDKShareMessengerGenericTemplateImageAspectRatio imageAspectRatio)
{
switch (imageAspectRatio) {
case FBSDKShareMessengerGenericTemplateImageAspectRatioSquare:
return @"square";
case FBSDKShareMessengerGenericTemplateImageAspectRatioHorizontal:
return @"horizontal";
}
}
static NSDictionary *_SerializableButtonFromURLButton(FBSDKShareMessengerURLActionButton *button, BOOL isDefaultAction)
NSDictionary<NSString *, id> *SerializableButtonFromURLButton(FBSDKShareMessengerURLActionButton *button, BOOL isDefaultAction)
{
NSMutableDictionary *serializableButton = [NSMutableDictionary dictionary];
@@ -128,164 +94,52 @@ static NSDictionary *_SerializableButtonFromURLButton(FBSDKShareMessengerURLActi
return serializableButton;
}
static NSArray *_SerializableButtonsFromButton(id<FBSDKShareMessengerActionButton> button)
NSArray<NSDictionary<NSString *, id> *> *SerializableButtonsFromButton(id<FBSDKShareMessengerActionButton> button)
{
// Return NSArray even though there is just one button to match proper json structure
NSMutableArray *serializableButtons = [NSMutableArray array];
NSMutableArray<NSDictionary<NSString *, id> *> *serializableButtons = [NSMutableArray array];
if ([button isKindOfClass:[FBSDKShareMessengerURLActionButton class]]) {
[FBSDKInternalUtility array:serializableButtons addObject:_SerializableButtonFromURLButton(button, NO)];
[FBSDKInternalUtility array:serializableButtons addObject:SerializableButtonFromURLButton(button, NO)];
}
return serializableButtons;
}
static NSArray *_SerializableGenericTemplateElementsFromElements(NSArray<FBSDKShareMessengerGenericTemplateElement *> *elements)
{
NSMutableArray *serializableElements = [NSMutableArray array];
for (FBSDKShareMessengerGenericTemplateElement *element in elements) {
NSMutableDictionary *elementDictionary = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:elementDictionary setObject:element.title forKey:@"title"];
[FBSDKInternalUtility dictionary:elementDictionary setObject:element.subtitle forKey:@"subtitle"];
[FBSDKInternalUtility dictionary:elementDictionary setObject:element.imageURL.absoluteString forKey:@"image_url"];
[FBSDKInternalUtility dictionary:elementDictionary setObject:_SerializableButtonsFromButton(element.button) forKey:kButtonsKey];
if ([element.defaultAction isKindOfClass:[FBSDKShareMessengerURLActionButton class]]) {
[FBSDKInternalUtility dictionary:elementDictionary setObject:_SerializableButtonFromURLButton(element.defaultAction, YES) forKey:@"default_action"];
}
[serializableElements addObject:elementDictionary];
}
return serializableElements;
}
static NSArray *_SerializableMediaTemplateContentFromContent(FBSDKShareMessengerMediaTemplateContent *mediaTemplateContent)
{
NSMutableArray *serializableMediaTemplateContent = [NSMutableArray array];
NSMutableDictionary *mediaTemplateContentDictionary = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:_MediaTypeString(mediaTemplateContent.mediaType) forKey:@"media_type"];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:mediaTemplateContent.mediaURL.absoluteString forKey:@"url"];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:mediaTemplateContent.attachmentID forKey:@"attachment_id"];
[FBSDKInternalUtility dictionary:mediaTemplateContentDictionary setObject:_SerializableButtonsFromButton(mediaTemplateContent.button) forKey:kButtonsKey];
[serializableMediaTemplateContent addObject:mediaTemplateContentDictionary];
return serializableMediaTemplateContent;
}
static NSArray *_SerializableOpenGraphMusicTemplateContentFromContent(FBSDKShareMessengerOpenGraphMusicTemplateContent *openGraphMusicTemplateContent)
{
NSMutableArray *serializableOpenGraphMusicTemplateContent = [NSMutableArray array];
NSMutableDictionary *openGraphMusicTemplateContentDictionary = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:openGraphMusicTemplateContentDictionary setObject:openGraphMusicTemplateContent.url.absoluteString forKey:@"url"];
[FBSDKInternalUtility dictionary:openGraphMusicTemplateContentDictionary setObject:_SerializableButtonsFromButton(openGraphMusicTemplateContent.button) forKey:kButtonsKey];
[serializableOpenGraphMusicTemplateContent addObject:openGraphMusicTemplateContentDictionary];
return serializableOpenGraphMusicTemplateContent;
}
static NSString *_MediaTemplateURLSerializationKey(NSURL *mediaURL)
{
if (_URLHasFacebookDomain(mediaURL)) {
return @"facebook_media_url";
} else {
return @"image_url";
}
}
+ (void)_addToParameters:(NSMutableDictionary *)parameters
contentForShare:(NSMutableDictionary *)contentForShare
contentForPreview:(NSMutableDictionary *)contentForPreview
+ (void)addToParameters:(NSMutableDictionary<NSString *, id> *)parameters
contentForShare:(NSMutableDictionary<NSString *, id> *)contentForShare
contentForPreview:(NSMutableDictionary<NSString *, id> *)contentForPreview
{
NSError *error = nil;
NSData *contentForShareData = [NSJSONSerialization dataWithJSONObject:contentForShare options:kNilOptions error:&error];
if (!error && contentForShareData) {
NSString *contentForShareDataString = [[NSString alloc] initWithData:contentForShareData encoding:NSUTF8StringEncoding];
NSMutableDictionary *messengerShareContent = [NSMutableDictionary dictionary];
NSMutableDictionary<NSString *, id> *messengerShareContent = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:messengerShareContent setObject:contentForShareDataString forKey:@"content_for_share"];
[FBSDKInternalUtility dictionary:messengerShareContent setObject:contentForPreview forKey:@"content_for_preview"];
[FBSDKInternalUtility dictionary:parameters setObject:messengerShareContent forKey:@"messenger_share_content"];
}
}
+ (void)addToParameters:(NSMutableDictionary *)parameters
forShareMessengerGenericTemplateContent:(FBSDKShareMessengerGenericTemplateContent *)genericTemplateContent
+ (BOOL)validateMessengerActionButton:(id<FBSDKShareMessengerActionButton>)button
isDefaultActionButton:(BOOL)isDefaultActionButton
pageID:(NSString *)pageID
error:(NSError *__autoreleasing *)errorRef
{
NSMutableDictionary *payload = [NSMutableDictionary dictionary];
[payload setObject:@"generic" forKey:kTemplateTypeKey];
[payload setObject:@(genericTemplateContent.isSharable) forKey:@"sharable"];
[payload setObject:_ImageAspectRatioString(genericTemplateContent.imageAspectRatio) forKey:@"image_aspect_ratio"];
[payload setObject:_SerializableGenericTemplateElementsFromElements(@[genericTemplateContent.element]) forKey:kElementsKey];
NSMutableDictionary *attachment = [NSMutableDictionary dictionary];
[attachment setObject:kTemplateKey forKey:kTypeKey];
[attachment setObject:payload forKey:kPayloadKey];
NSMutableDictionary *contentForShare = [NSMutableDictionary dictionary];
[contentForShare setObject:attachment forKey:kAttachmentKey];
FBSDKShareMessengerGenericTemplateElement *firstElement = genericTemplateContent.element;
NSMutableDictionary *contentForPreview = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:contentForPreview setObject:@"DEFAULT" forKey:@"preview_type"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:firstElement.title forKey:@"title"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:firstElement.subtitle forKey:@"subtitle"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:firstElement.imageURL.absoluteString forKey:@"image_url"];
if (firstElement.button) {
_AddToContentPreviewDictionaryForButton(contentForPreview, firstElement.button);
} else {
_AddToContentPreviewDictionaryForButton(contentForPreview, firstElement.defaultAction);
if (!button) {
return YES;
}
else if ([button isKindOfClass:[FBSDKShareMessengerURLActionButton class]]) {
FBSDKShareMessengerURLActionButton *urlActionButton = (FBSDKShareMessengerURLActionButton *)button;
return [FBSDKShareUtility validateRequiredValue:urlActionButton.url name:@"button.url" error:errorRef] &&
(!isDefaultActionButton ? [FBSDKShareUtility validateRequiredValue:urlActionButton.title name:@"button.title" error:errorRef] : YES) &&
(urlActionButton.isMessengerExtensionURL ? [FBSDKShareUtility validateRequiredValue:pageID name:@"content pageID" error:errorRef] : YES);
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"buttons" value:button message:nil];
}
return NO;
}
[self _addToParameters:parameters contentForShare:contentForShare contentForPreview:contentForPreview];
}
+ (void)addToParameters:(NSMutableDictionary *)parameters
forShareMessengerMediaTemplateContent:(FBSDKShareMessengerMediaTemplateContent *)mediaTemplateContent
{
NSMutableDictionary *payload = [NSMutableDictionary dictionary];
[payload setObject:@"media" forKey:kTemplateTypeKey];
[payload setObject:_SerializableMediaTemplateContentFromContent(mediaTemplateContent) forKey:kElementsKey];
NSMutableDictionary *attachment = [NSMutableDictionary dictionary];
[attachment setObject:kTemplateKey forKey:kTypeKey];
[attachment setObject:payload forKey:kPayloadKey];
NSMutableDictionary *contentForShare = [NSMutableDictionary dictionary];
[contentForShare setObject:attachment forKey:kAttachmentKey];
NSMutableDictionary *contentForPreview = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:contentForPreview setObject:@"DEFAULT" forKey:@"preview_type"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:mediaTemplateContent.attachmentID forKey:@"attachment_id"];
[FBSDKInternalUtility dictionary:contentForPreview
setObject:mediaTemplateContent.mediaURL.absoluteString
forKey:_MediaTemplateURLSerializationKey(mediaTemplateContent.mediaURL)];
[FBSDKInternalUtility dictionary:contentForPreview setObject:_MediaTypeString(mediaTemplateContent.mediaType) forKey:@"media_type"];
_AddToContentPreviewDictionaryForButton(contentForPreview, mediaTemplateContent.button);
[self _addToParameters:parameters contentForShare:contentForShare contentForPreview:contentForPreview];
}
+ (void)addToParameters:(NSMutableDictionary *)parameters
forShareMessengerOpenGraphMusicTemplateContent:(FBSDKShareMessengerOpenGraphMusicTemplateContent *)openGraphMusicTemplate
{
NSMutableDictionary *payload = [NSMutableDictionary dictionary];
[payload setObject:@"open_graph" forKey:kTemplateTypeKey];
[payload setObject:_SerializableOpenGraphMusicTemplateContentFromContent(openGraphMusicTemplate) forKey:kElementsKey];
NSMutableDictionary *attachment = [NSMutableDictionary dictionary];
[attachment setObject:kTemplateKey forKey:kTypeKey];
[attachment setObject:payload forKey:kPayloadKey];
NSMutableDictionary *contentForShare = [NSMutableDictionary dictionary];
[contentForShare setObject:attachment forKey:kAttachmentKey];
NSMutableDictionary *contentForPreview = [NSMutableDictionary dictionary];
[FBSDKInternalUtility dictionary:contentForPreview setObject:@"OPEN_GRAPH" forKey:@"preview_type"];
[FBSDKInternalUtility dictionary:contentForPreview setObject:openGraphMusicTemplate.url.absoluteString forKey:@"open_graph_url"];
_AddToContentPreviewDictionaryForButton(contentForPreview, openGraphMusicTemplate.button);
[self _addToParameters:parameters contentForShare:contentForShare contentForPreview:contentForPreview];
}
@end
@@ -25,12 +25,6 @@
#import <FBSDKShareKit/FBSDKShareVideoContent.h>
#import <FBSDKShareKit/FBSDKSharingContent.h>
#if !TARGET_OS_TV
#import <FBSDKShareKit/FBSDKAppInviteContent.h>
#import <FBSDKShareKit/FBSDKGameRequestContent.h>
#import <FBSDKShareKit/FBSDKShareCameraEffectContent.h>
#endif
@interface FBSDKShareUtility : NSObject
+ (void)assertCollection:(id<NSFastEnumeration>)collection ofClass:itemClass name:(NSString *)name;
@@ -38,40 +32,46 @@
+ (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;
+ (void)buildAsyncWebPhotoContent:(FBSDKSharePhotoContent *)content
completionHandler:(void(^)(BOOL, NSString *, NSDictionary *))completion;
+ (NSDictionary *)convertOpenGraphValues:(NSDictionary *)dictionary;
+ (id)convertOpenGraphValue:(id)value;
+ (NSDictionary<NSString *, id> *)convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)container
requireNamespace:(BOOL)requireNamespace;
+ (NSDictionary<NSString *, id> *)convertOpenGraphValues:(NSDictionary<NSString *, id> *)dictionary;
+ (NSDictionary<NSString *, id> *)convertPhoto:(FBSDKSharePhoto *)photo;
+ (NSDictionary *)feedShareDictionaryForContent:(id<FBSDKSharingContent>)content;
+ (NSString *)getOpenGraphNameAndNamespaceFromFullName:(NSString *)fullName namespace:(NSString **)namespace;
+ (NSString *)hashtagStringFromHashtag:(FBSDKHashtag *)hashtag;
+ (UIImage *)imageWithCircleColor:(UIColor *)color
canvasSize:(CGSize)canvasSize
circleSize:(CGSize)circleSize;
+ (NSDictionary *)parametersForShareContent:(id<FBSDKSharingContent>)shareContent
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
shouldFailOnDataError:(BOOL)shouldFailOnDataError;
+ (void)testShareContent:(id<FBSDKSharingContent>)shareContent
containsMedia:(BOOL *)containsMediaRef
containsPhotos:(BOOL *)containsPhotosRef
containsVideos:(BOOL *)containsVideosRef;
+ (BOOL)shareMediaContentContainsPhotosAndVideos:(FBSDKShareMediaContent *)shareMediaContent;
+ (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef;
+ (BOOL)validateAssetLibraryURLsWithShareMediaContent:(FBSDKShareMediaContent *)mediaContent 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)validateShareMediaContent:(FBSDKShareMediaContent *)mediaContent 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)validateShareCameraEffectContent:(FBSDKShareCameraEffectContent *)ShareCameraEffectContent
error:(NSError *__autoreleasing *)errorRef;
+ (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef;
#endif
+ (BOOL)validateArgumentWithName:(NSString *)argumentName
value:(NSUInteger)value
isIn:(NSArray<NSNumber *> *)possibleValues
error:(NSError *__autoreleasing *)errorRef;
+ (BOOL)validateArray:(NSArray<id> *)array
minCount:(NSUInteger)minCount
maxCount:(NSUInteger)maxCount
name:(NSString *)name
error:(NSError *__autoreleasing *)errorRef;
+ (BOOL)validateNetworkURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef;
+ (BOOL)validateRequiredValue:(id)value name:(NSString *)name error:(NSError *__autoreleasing *)errorRef;
+ (BOOL)validateShareContent:(id<FBSDKSharingContent>)shareContent
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
error:(NSError *__autoreleasing *)errorRef;
@end
@@ -20,29 +20,8 @@
#import <FBSDKShareKit/FBSDKHashtag.h>
#import "FBSDKCoreKit+Internal.h"
#import "FBSDKShareConstants.h"
#import "FBSDKShareError.h"
#import "FBSDKShareLinkContent+Internal.h"
#import "FBSDKShareMediaContent.h"
#import "FBSDKShareOpenGraphContent.h"
#import "FBSDKShareOpenGraphObject.h"
#import "FBSDKSharePhoto.h"
#import "FBSDKSharePhotoContent.h"
#import "FBSDKShareVideo.h"
#import "FBSDKShareVideoContent.h"
#import "FBSDKSharingContent.h"
#if !TARGET_OS_TV
#import "FBSDKCameraEffectArguments+Internal.h"
#import "FBSDKCameraEffectTextures+Internal.h"
#import "FBSDKShareMessengerContentUtility.h"
#import "FBSDKShareMessengerGenericTemplateContent.h"
#import "FBSDKShareMessengerGenericTemplateElement.h"
#import "FBSDKShareMessengerMediaTemplateContent.h"
#import "FBSDKShareMessengerOpenGraphMusicTemplateContent.h"
#import "FBSDKShareMessengerURLActionButton.h"
#endif
@implementation FBSDKShareUtility
@@ -138,31 +117,32 @@
error:(NSError *__autoreleasing *)errorRef
{
NSString *methodName = nil;
NSDictionary *parameters = nil;
NSMutableDictionary<NSString *, id> *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];
NSDictionary<NSString *, id> *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;
parameters = [NSMutableDictionary new];
[FBSDKInternalUtility dictionary:parameters setObject:action.actionType forKey:@"action_type"];
[FBSDKInternalUtility dictionary:parameters setObject:propertiesJSON forKey:@"action_properties"];
} else {
methodName = @"share";
if (linkContent.contentURL != nil) {
parameters = @{ @"href": linkContent.contentURL.absoluteString };
if ([content isKindOfClass:[FBSDKShareLinkContent class]]) {
FBSDKShareLinkContent *const linkContent = (FBSDKShareLinkContent *)content;
if (linkContent.contentURL != nil) {
parameters = [NSMutableDictionary new];
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL.absoluteString forKey:@"href"];
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.quote forKey:@"quote"];
}
}
}
NSString *hashtagString = [self hashtagStringFromHashtag:content.hashtag];
if (hashtagString != nil) {
NSMutableDictionary *mutableParameters = [parameters mutableCopy];
[FBSDKInternalUtility dictionary:mutableParameters setObject:hashtagString forKey:@"hashtag"];
parameters = [mutableParameters copy];
if (parameters) {
NSString *hashtagString = [self hashtagStringFromHashtag:content.hashtag];
[FBSDKInternalUtility dictionary:parameters setObject:hashtagString forKey:@"hashtag"];
}
if (methodNameRef != NULL) {
*methodNameRef = methodName;
@@ -180,25 +160,20 @@
completionHandler:(void(^)(BOOL, NSString *, NSDictionary *))completion
{
void(^stageImageCompletion)(NSArray<NSString *> *) = ^(NSArray<NSString *> *stagedURIs) {
NSString *methodName = @"share";
NSMutableDictionary *parameters = [[FBSDKShareUtility parametersForShareContent:content
shouldFailOnDataError:NO] mutableCopy];
NSString *const methodName = @"share";
NSMutableDictionary<NSString *, id> *const parameters =
[[FBSDKShareUtility parametersForShareContent:content
bridgeOptions:FBSDKShareBridgeOptionsWebHashtag
shouldFailOnDataError:NO] mutableCopy];
[parameters removeObjectForKey:@"photos"];
NSString *stagedURIJSONString = [FBSDKInternalUtility JSONStringForObject:stagedURIs
error:nil
invalidObjectHandler:NULL];
NSString *const stagedURIJSONString = [FBSDKInternalUtility JSONStringForObject:stagedURIs
error:nil
invalidObjectHandler:NULL];
[FBSDKInternalUtility dictionary:parameters
setObject:stagedURIJSONString
forKey:@"media"];
NSString *hashtagString = [self hashtagStringFromHashtag:content.hashtag];
if (hashtagString != nil) {
[FBSDKInternalUtility dictionary:parameters
setObject:hashtagString
forKey:@"hashtag"];
}
if (completion != NULL) {
completion(YES, methodName, [parameters copy]);
}
@@ -238,18 +213,18 @@
}
}
+ (NSDictionary *)convertOpenGraphValues:(NSDictionary *)dictionary
+ (NSDictionary<NSString *, id> *)convertOpenGraphValues:(NSDictionary<NSString *, id> *)dictionary
{
NSMutableDictionary *convertedDictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary<NSString *, id> *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
+ (NSDictionary<NSString *, id> *)feedShareDictionaryForContent:(id<FBSDKSharingContent>)content
{
NSMutableDictionary *parameters = nil;
NSMutableDictionary<NSString *, id> *parameters = nil;
#pragma clang diagnostic pop
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if ([content isKindOfClass:[FBSDKShareLinkContent class]]) {
@@ -298,34 +273,44 @@
return image;
}
+ (NSDictionary *)parametersForShareContent:(id<FBSDKSharingContent>)shareContent
shouldFailOnDataError:(BOOL)shouldFailOnDataError
+ (NSDictionary<NSString *, id> *)parametersForShareContent:(id<FBSDKSharingContent>)shareContent
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
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];
#if !TARGET_OS_TV
} else if ([shareContent isKindOfClass:[FBSDKShareMessengerGenericTemplateContent class]]) {
[FBSDKShareMessengerContentUtility addToParameters:parameters
forShareMessengerGenericTemplateContent:(FBSDKShareMessengerGenericTemplateContent *)shareContent];
} else if ([shareContent isKindOfClass:[FBSDKShareMessengerMediaTemplateContent class]]) {
[FBSDKShareMessengerContentUtility addToParameters:parameters
forShareMessengerMediaTemplateContent:(FBSDKShareMessengerMediaTemplateContent *)shareContent];
} else if ([shareContent isKindOfClass:[FBSDKShareMessengerOpenGraphMusicTemplateContent class]]) {
[FBSDKShareMessengerContentUtility addToParameters:parameters
forShareMessengerOpenGraphMusicTemplateContent:(FBSDKShareMessengerOpenGraphMusicTemplateContent *)shareContent];
} else if ([shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) {
[self _addToParameters:parameters forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)shareContent];
#endif
NSMutableDictionary<NSString *, id> *parameters = [[NSMutableDictionary alloc] init];
// FBSDKSharingContent parameters
NSString *const hashtagString = [self hashtagStringFromHashtag:shareContent.hashtag];
if (hashtagString.length > 0) {
// When hashtag support was originally added, the Facebook app supported an array of hashtags.
// This was changed to support a single hashtag; however, the mobile app still expects to receive an array.
// When hashtag support was added to web dialogs, a single hashtag was passed as a string.
if (bridgeOptions & FBSDKShareBridgeOptionsWebHashtag) {
[FBSDKInternalUtility dictionary:parameters setObject:hashtagString forKey:@"hashtag"];
} else {
[FBSDKInternalUtility dictionary:parameters setObject:@[hashtagString] forKey:@"hashtags"];
}
}
[FBSDKInternalUtility dictionary:parameters setObject:shareContent.pageID forKey:@"pageID"];
[FBSDKInternalUtility dictionary:parameters setObject:shareContent.shareUUID forKey:@"shareUUID"];
if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
FBSDKShareOpenGraphAction *const 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"];
}
parameters[@"dataFailuresFatal"] = @(shouldFailOnDataError);
// media/destination-specific content parameters
if ([shareContent respondsToSelector:@selector(addToParameters:bridgeOptions:)]) {
[shareContent addToParameters:parameters bridgeOptions:bridgeOptions];
}
return [parameters copy];
}
@@ -372,90 +357,6 @@
}
}
#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] &&
[self validatePromoCodeWithError:appInviteContent error:errorRef]);
}
+ (BOOL)validatePromoCodeWithError:(FBSDKAppInviteContent *)appInviteContent error:(NSError *__autoreleasing *)errorRef
{
NSString *promoText = appInviteContent.promotionText;
NSString *promoCode = appInviteContent.promotionCode;
NSMutableCharacterSet *alphanumericWithSpaces = [NSMutableCharacterSet alphanumericCharacterSet];
[alphanumericWithSpaces formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
if ([promoText length] > 0 || [promoCode length] > 0) {
// Check for validity of promo text and promo code.
if (!([promoText length] > 0 && [promoText length] <= 80)) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionText" value:promoText message:@"Invalid value for promotionText, promotionText has to be between 1 and 80 characters long."];
}
return NO;
}
if (!([promoCode length] <= 10)) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionCode" value:promoCode message:@"Invalid value for promotionCode, promotionCode has to be between 0 and 10 characters long and is required when promoCode is set."];
}
return NO;
}
if ([promoText rangeOfCharacterFromSet:[alphanumericWithSpaces invertedSet]].location != NSNotFound) {
if(errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionText" value:promoText message:@"Invalid value for promotionText, promotionText can contain only alphanumeric characters and spaces."];
}
return NO;
}
if ([promoCode length] > 0 && [promoCode rangeOfCharacterFromSet:[alphanumericWithSpaces invertedSet]].location != NSNotFound) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionCode" value:promoCode message:@"Invalid value for promotionCode, promotionCode can contain only alphanumeric characters and spaces."];
}
return NO;
}
}
if (errorRef != NULL) {
*errorRef = nil;
}
return YES;
}
+ (BOOL)validateShareCameraEffectContent:(FBSDKShareCameraEffectContent *)ShareCameraEffectContent
error:(NSError *__autoreleasing *)errorRef {
NSString *effectID = ShareCameraEffectContent.effectID;
NSCharacterSet* nonDigitCharacters = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([effectID length] > 0) {
if ([effectID rangeOfCharacterFromSet:nonDigitCharacters].location != NSNotFound) {
if (errorRef != NULL) {
*errorRef = [FBSDKError invalidArgumentErrorWithName:@"effectID"
value:effectID
message:@"Invalid value for effectID, effectID can contain only numerical characters."];
}
return NO;
}
}
return YES;
}
#endif
+ (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
{
FBSDKShareVideo *video = videoContent.video;
NSURL *videoURL = video.videoURL;
return [self _validateAssetLibraryVideoURL:videoURL name:name error:errorRef];
}
+ (BOOL)validateAssetLibraryURLsWithShareMediaContent:(FBSDKShareMediaContent *)mediaContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
{
for (id media in mediaContent.media) {
@@ -469,101 +370,15 @@
return YES;
}
#if !TARGET_OS_TV
+ (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef
+ (BOOL)validateShareContent:(id<FBSDKSharingContent>)shareContent
bridgeOptions:(FBSDKShareBridgeOptions)bridgeOptions
error:(NSError *__autoreleasing *)errorRef
{
if (![self _validateRequiredValue:gameRequestContent name:@"content" error:errorRef]
|| ![self _validateRequiredValue:gameRequestContent.message name:@"message" error:errorRef]) {
if (![self validateRequiredValue:shareContent name:@"shareContent" 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:[FBSDKShareMediaContent class]]) {
return [self validateShareMediaContent:(FBSDKShareMediaContent *)shareContent error:errorRef];
} else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) {
return [self validateShareOpenGraphContent:(FBSDKShareOpenGraphContent *)shareContent error:errorRef];
#if !TARGET_OS_TV
} else if ([shareContent isKindOfClass:[FBSDKShareMessengerMediaTemplateContent class]]) {
return [self validateMessengerMediaTemplateContent:(FBSDKShareMessengerMediaTemplateContent *)shareContent error:errorRef];
} else if ([shareContent isKindOfClass:[FBSDKShareMessengerGenericTemplateContent class]]) {
return [self validateMessengerGenericTemplateContent:(FBSDKShareMessengerGenericTemplateContent *)shareContent error:errorRef];
} else if ([shareContent isKindOfClass:[FBSDKShareMessengerOpenGraphMusicTemplateContent class]]) {
return [self validateMessengerOpenGraphMusicTemplateContent:(FBSDKShareMessengerOpenGraphMusicTemplateContent *)shareContent error:errorRef];
} else if ([shareContent isKindOfClass:[FBSDKShareCameraEffectContent class]]) {
return [self validateShareCameraEffectContent:(FBSDKShareCameraEffectContent *)shareContent error:errorRef];
#endif
else if ([shareContent respondsToSelector:@selector(validateWithOptions:error:)]) {
return [shareContent validateWithOptions:bridgeOptions error:errorRef];
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:nil];
@@ -572,181 +387,6 @@
}
}
+ (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)validateShareMediaContent:(FBSDKShareMediaContent *)mediaContent error:(NSError *__autoreleasing *)errorRef
{
NSArray *medias = mediaContent.media;
if (![self _validateRequiredValue:mediaContent name:@"shareContent" error:errorRef] ||
![self _validateArray:medias minCount:1 maxCount:20 name:@"photos" error:errorRef]) {
return NO;
}
int videoCount = 0;
for (id media in medias) {
if ([media isKindOfClass:[FBSDKSharePhoto class]]) {
FBSDKSharePhoto *photo = (FBSDKSharePhoto *)media;
if (!photo.image) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media"
value:media
message:@"photos must have UIImages"];
}
return NO;
}
} else if ([media isKindOfClass:[FBSDKShareVideo class]]) {
if (videoCount > 0) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media"
value:media
message:@"Only 1 video is allowed"];
return NO;
}
}
videoCount++;
FBSDKShareVideo *video = (FBSDKShareVideo *)media;
NSURL *videoURL = video.videoURL;
if (![self _validateRequiredValue:video name:@"video" error:errorRef] &&
[self _validateRequiredValue:videoURL name:@"videoURL" error:errorRef]) {
return NO;
}
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media"
value:media
message:@"Only FBSDKSharePhoto and FBSDKShareVideo are allowed in `media` property"];
}
return NO;
}
}
return YES;
}
+ (BOOL)validateShareLinkContent:(FBSDKShareLinkContent *)linkContent error:(NSError *__autoreleasing *)errorRef
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return ([self _validateRequiredValue:linkContent name:@"shareContent" error:errorRef] &&
[self _validateNetworkURL:linkContent.contentURL name:@"contentURL" error:errorRef] &&
[self _validateNetworkURL:linkContent.imageURL name:@"imageURL" error:errorRef]);
#pragma clang diagnostic pop
}
+ (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]);
}
#if !TARGET_OS_TV
+ (BOOL)validateMessengerMediaTemplateContent:(FBSDKShareMessengerMediaTemplateContent *)messengerMediaTemplateContent
error:(NSError *__autoreleasing *)errorRef
{
if (!messengerMediaTemplateContent.mediaURL && !messengerMediaTemplateContent.attachmentID) {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"attachmentID/mediaURL" message:@"Must specify either attachmentID or mediaURL"];
}
return NO;
}
return [self _validateMessengerActionButton:messengerMediaTemplateContent.button
isDefaultActionButton:NO
pageID:messengerMediaTemplateContent.pageID
error:errorRef];
}
+ (BOOL)validateMessengerGenericTemplateContent:(FBSDKShareMessengerGenericTemplateContent *)genericTemplateContent
error:(NSError *__autoreleasing *)errorRef
{
return [self _validateRequiredValue:genericTemplateContent.element.title name:@"element.title" error:errorRef] &&
[self _validateMessengerActionButton:genericTemplateContent.element.defaultAction
isDefaultActionButton:YES
pageID:genericTemplateContent.pageID
error:errorRef] &&
[self _validateMessengerActionButton:genericTemplateContent.element.button
isDefaultActionButton:NO
pageID:genericTemplateContent.pageID
error:errorRef];
}
+ (BOOL)validateMessengerOpenGraphMusicTemplateContent:(FBSDKShareMessengerOpenGraphMusicTemplateContent *)openGraphMusicTemplateContent
error:(NSError *__autoreleasing *)errorRef
{
return [self _validateRequiredValue:openGraphMusicTemplateContent.url name:@"url" error:errorRef] &&
[self _validateRequiredValue:openGraphMusicTemplateContent.pageID name:@"pageID" error:errorRef] &&
[self _validateMessengerActionButton:openGraphMusicTemplateContent.button
isDefaultActionButton:NO
pageID:openGraphMusicTemplateContent.pageID
error:errorRef];
}
+ (BOOL)_validateMessengerActionButton:(id<FBSDKShareMessengerActionButton>)button
isDefaultActionButton:(BOOL)isDefaultActionButton
pageID:(NSString *)pageID
error:(NSError *__autoreleasing *)errorRef
{
if (!button) {
return YES;
}
if ([button isKindOfClass:[FBSDKShareMessengerURLActionButton class]]) {
return [self _validateURLActionButton:(FBSDKShareMessengerURLActionButton *)button
isDefaultActionButton:isDefaultActionButton
pageID:pageID
error:errorRef];
} else {
if (errorRef != NULL) {
*errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"buttons" value:button message:nil];
}
return NO;
}
}
+ (BOOL)_validateURLActionButton:(FBSDKShareMessengerURLActionButton *)urlActionButton
isDefaultActionButton:(BOOL)isDefaultActionButton
pageID:(NSString *)pageID
error:(NSError *__autoreleasing *)errorRef
{
return [self _validateRequiredValue:urlActionButton.url name:@"button.url" error:errorRef] &&
(!isDefaultActionButton ? [self _validateRequiredValue:urlActionButton.title name:@"button.title" error:errorRef] : YES) &&
(urlActionButton.isMessengerExtensionURL ? [self _validateRequiredValue:pageID name:@"content pageID" error:errorRef] : YES);
}
#endif
+ (BOOL)shareMediaContentContainsPhotosAndVideos:(FBSDKShareMediaContent *)shareMediaContent
{
BOOL containsPhotos = NO;
@@ -765,131 +405,12 @@
#pragma mark - Helper Methods
+ (void)_addToParameters:(NSMutableDictionary *)parameters forShareContent:(id<FBSDKSharingContent>)shareContent
{
NSString *hashtagString = [self hashtagStringFromHashtag:shareContent.hashtag];
if (hashtagString != nil) {
[FBSDKInternalUtility dictionary:parameters setObject:@[hashtagString] forKey:@"hashtags"];
}
[FBSDKInternalUtility dictionary:parameters setObject:shareContent.pageID forKey:@"pageID"];
[FBSDKInternalUtility dictionary:parameters setObject:shareContent.shareUUID forKey:@"shareUUID"];
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
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[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"];
/**
Pass link parameter as "messenger_link" due to versioning requirements for message dialog flow.
We will only use the new share flow we developed if messenger_link is present, not link.
*/
[FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL forKey:@"messenger_link"];
#pragma clang diagnostic pop
}
+ (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;
}
#if !TARGET_OS_TV
+ (void)_addToParameters:(NSMutableDictionary *)parameters
forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)cameraEffectContent
{
[FBSDKInternalUtility dictionary:parameters
setObject:cameraEffectContent.effectID
forKey:@"effect_id"];
[FBSDKInternalUtility dictionary:parameters
setObject:[self _convertCameraEffectArguments:cameraEffectContent.effectArguments]
forKey:@"effect_arguments"];
[FBSDKInternalUtility dictionary:parameters
setObject:[self _convertCameraEffectTextures:cameraEffectContent.effectTextures]
forKey:@"effect_textures"];
}
+ (NSString *)_convertCameraEffectArguments:(FBSDKCameraEffectArguments *)arguments
{
// Convert a camera effect arguments container to a JSON string.
if (arguments == nil) {
return nil;
}
return [FBSDKInternalUtility JSONStringForObject:[arguments allArguments]
error:NULL
invalidObjectHandler:NULL];
}
+ (NSData *)_convertCameraEffectTextures:(FBSDKCameraEffectTextures *)textures
{
if (textures == nil) {
return nil;
}
// Convert the entire textures dictionary into one NSData, because
// the existing API protocol only allows one value to be put into the pasteboard.
NSDictionary *texturesDict = [textures allTextures];
NSMutableDictionary *texturesDataDict = [NSMutableDictionary dictionaryWithCapacity:texturesDict.count];
[texturesDict enumerateKeysAndObjectsUsingBlock:^(NSString *key, UIImage *img, BOOL *stop) {
// Convert UIImages to NSData, because UIImage is not archivable.
[texturesDataDict setObject:UIImagePNGRepresentation(img) forKey:key];
}];
return [NSKeyedArchiver archivedDataWithRootObject:texturesDataDict];
}
#endif
+ (id)_convertObject:(id)object
{
if ([object isKindOfClass:[FBSDKShareOpenGraphValueContainer class]]) {
object = [self _convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object requireNamespace:YES];
object = [self convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object requireNamespace:YES];
} else if ([object isKindOfClass:[FBSDKSharePhoto class]]) {
object = [self _convertPhoto:(FBSDKSharePhoto *)object];
object = [self convertPhoto:(FBSDKSharePhoto *)object];
} else if ([object isKindOfClass:[NSArray class]]) {
NSMutableArray *array = [[NSMutableArray alloc] init];
for (id item in (NSArray *)object) {
@@ -900,11 +421,11 @@ forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)cameraEffectContent
return object;
}
+ (NSDictionary *)_convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)container
requireNamespace:(BOOL)requireNamespace
+ (NSDictionary<NSString *, id> *)convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)container
requireNamespace:(BOOL)requireNamespace
{
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
NSMutableDictionary<NSString *, id> *dictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary<NSString *, id> *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]]) {
@@ -954,12 +475,12 @@ forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)cameraEffectContent
return fullName;
}
+ (NSDictionary *)_convertPhoto:(FBSDKSharePhoto *)photo
+ (NSDictionary<NSString *, id> *)convertPhoto:(FBSDKSharePhoto *)photo
{
if (!photo) {
return nil;
}
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary<NSString *, id> *dictionary = [[NSMutableDictionary alloc] init];
dictionary[@"user_generated"] = @(photo.userGenerated);
[FBSDKInternalUtility dictionary:dictionary setObject:photo.caption forKey:@"caption"];
@@ -1081,11 +602,11 @@ forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)cameraEffectContent
}
}
+ (BOOL)_validateArray:(NSArray *)array
minCount:(NSUInteger)minCount
maxCount:(NSUInteger)maxCount
name:(NSString *)name
error:(NSError *__autoreleasing *)errorRef
+ (BOOL)validateArray:(NSArray<id> *)array
minCount:(NSUInteger)minCount
maxCount:(NSUInteger)maxCount
name:(NSString *)name
error:(NSError *__autoreleasing *)errorRef
{
NSUInteger count = [array count];
if ((count < minCount) || (count > maxCount)) {
@@ -1139,7 +660,7 @@ forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)cameraEffectContent
return YES;
}
+ (BOOL)_validateNetworkURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
+ (BOOL)validateNetworkURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
{
if (!URL || [FBSDKInternalUtility isBrowserURL:URL]) {
if (errorRef != NULL) {
@@ -1154,7 +675,7 @@ forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)cameraEffectContent
}
}
+ (BOOL)_validateRequiredValue:(id)value name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
+ (BOOL)validateRequiredValue:(id)value name:(NSString *)name error:(NSError *__autoreleasing *)errorRef
{
if (!value ||
([value isKindOfClass:[NSString class]] && ![(NSString *)value length]) ||
@@ -1171,10 +692,10 @@ forShareCameraEffectContent:(FBSDKShareCameraEffectContent *)cameraEffectContent
return YES;
}
+ (BOOL)_validateArgumentWithName:(NSString *)argumentName
value:(NSUInteger)value
isIn:(NSArray *)possibleValues
error:(NSError *__autoreleasing *)errorRef
+ (BOOL)validateArgumentWithName:(NSString *)argumentName
value:(NSUInteger)value
isIn:(NSArray<NSNumber *> *)possibleValues
error:(NSError *__autoreleasing *)errorRef
{
for (NSNumber *possibleValue in possibleValues) {
if (value == [possibleValue unsignedIntegerValue]) {
@@ -35,10 +35,10 @@
/**
Initialize videoUploader
- Parameter videoName: The file name of the video to be uploaded
- Parameter videoSize: The size of the video to be uploaded
- Parameter 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
- Parameter delegate: Receiver's delegate
@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;
@@ -81,23 +81,23 @@ NS_DESIGNATED_INITIALIZER;
/**
get chunk of the video to be uploaded in 'NSData' format
- Parameter videoUploader: The `FBSDKVideoUploader` object which is performing the upload process
- Parameter startOffset: The start offset of video chunk to be uploaded
- Parameter endOffset: The end offset of video chunk being to be uploaded
@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;
/**
Notify the delegate that upload process success.
- Parameter videoUploader: The `FBSDKVideoUploader` object which is performing the upload process
- Parameter results: The result from successful upload
@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;
/**
Notify the delegate that upload process fails.
- Parameter videoUploader: The `FBSDKVideoUploader` object which is performing the upload process
- Parameter error: The error object from unsuccessful upload
@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;
@@ -87,8 +87,8 @@ static NSString *const FBSDKVideoUploaderEdge = @"videos";
} else if (offsetDictionary == nil) {
return;
}
_uploadSessionID = uploadSessionID;
_videoID = videoID;
self->_uploadSessionID = uploadSessionID;
self->_videoID = videoID;
[self _startTransferRequestWithOffsetDictionary:offsetDictionary];
}
};
@@ -131,13 +131,13 @@ static NSString *const FBSDKVideoUploaderEdge = @"videos";
}
dispatch_async(dispatch_get_main_queue(), ^{
FBSDKGraphRequestDataAttachment *dataAttachment = [[FBSDKGraphRequestDataAttachment alloc] initWithData:data
filename:_videoName
filename:self->_videoName
contentType:nil];
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:self->_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_UPLOAD_SESSION_ID: self->_uploadSessionID,
FBSDK_SHARE_VIDEO_FILE_CHUNK: dataAttachment,
}
HTTPMethod:@"POST"];
@@ -178,7 +178,7 @@ static NSString *const FBSDKVideoUploaderEdge = @"videos";
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;
shareResult[FBSDK_SHARE_VIDEO_ID] = self->_videoID;
[self.delegate videoUploader:self didCompleteWithResults:shareResult];
}
}];
+41
View File
@@ -0,0 +1,41 @@
# 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 - <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](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.
-46
View File
@@ -1,46 +0,0 @@
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 - 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.