Facebook Live Video API, can I share a friend video stream programmatically? - ios

I want to share a Facebook video live stream on my own wall programmatically. I want to do it inside my app after a Facebook login made with the facebook sdk, something like a normal link sharing:
NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
[params setObject:link forKey:#"picture"];
[params setObject:LinkStringa forKey:#"link"];
[params setObject:ShareTextView.text forKey:#"message"];
[params setObject:[[FBSDKAccessToken currentAccessToken] tokenString] forKey:#"access_token"];
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"/me/feed"
parameters:params
HTTPMethod:#"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
// Handle the result
if (!error) {
}
else{
NSLog(#"error %#",error.description);
}
}];
I can't find mentions about sharing live video on Facebook documentation, only how create and publish live video. How can I share a live stream video?

You can use this method for that:
- (void)enableFacebookLiveStreamingWithCompletionHandler:(void(^)(NSString* facebookStreamURL, NSString* facebookStreamKey, NSError* error))completionHandler;
{
dispatch_async(dispatch_get_main_queue(), ^{
if ([[FBSDKAccessToken currentAccessToken] hasGranted:permissionPublishActions])
{
NSString* liveVideosRequestPath = [NSString stringWithFormat:#"/%#/live_videos",[FBSDKAccessToken currentAccessToken].userID];
FBSDKGraphRequest* request = [[FBSDKGraphRequest alloc] initWithGraphPath:liveVideosRequestPath parameters:nil HTTPMethod:#"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSLog(#"%#",[FBSDKAccessToken currentAccessToken].permissions);
if (error)
{
if (completionHandler)
completionHandler(#"",#"",error);
}
else
{
if (completionHandler)
completionHandler(#"rtmp://rtmp-api.facebook.com:80/rtmp/",[[result objectForKey:#"stream_url"] lastPathComponent],nil);
}
}];
}
});
}
For streaming via RTMP use this open source library: https://github.com/jgh-/VideoCore
There is a code for example:
self.vcSession = [[VCSimpleSession alloc] initWithVideoSize:CGSizeMake(854, 480) frameRate:30 bitrate:1000000 useInterfaceOrientation:NO];
[self.view addSubview:self.vcSession.previewView];
self.vcSession.previewView.frame = CGRectMake(40, 40, 320, 240);//self.view.bounds;
self.vcSession.delegate = self;
[self.vcSession startRtmpSessionWithURL:#"your rtmp:URL "andStreamKey:#"your stream key"];

Swift 3
you can check this repo
https://github.com/hansemannn/facebook-live-ios
How to use
var liveVideo: FBSDKLiveVideo!
override func viewDidLoad() {
super.viewDidLoad()
// Create the live video service
liveVideo = FBSDKLiveVideo(
delegate: self,
previewSize: self.view.bounds,
videoSize: CGSize(width: 1280, height: 720)
)
// Optional: Configure the live-video (see the source for all options)
liveVideo.privacy = .me // or .friends, .friendsOfFriends, .custom
liveVideo.audience = "me" // or your user-id, page-id, event-id, group-id, ...
// Optional: Add the preview view of the stream to your container view.
myView.addSubView(liveVideo.preview)
}

Found this link https://developers.facebook.com/docs/videos/live-video-api which states:
" Stream a Live Video
Once a live_video object is created, a stream_url and key will be returned in the response. The server URL will be http://rtmp-api.facebook.com/rtmp/ and the stream key will be everything after it. Use both in order to push video frames through your streaming software."
Let me know how it turns out though as I'm also starting an app with this functionality.

Related

Share on facebook when app is not configured

I want post something on Facebook. I have used SLComposeViewController for that. I just want to ask how can i share if user hasn't configured its app in phone.
Is there any way that I open it in browser and then post anything. Consider I want to post any string say "hello there" . So i keep this string , open safari and login there . After I am logged in the string is posted automatically
if SLComposeViewController.isAvailableForServiceType(SLServiceTypeFacebook) {
let fbShare:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
fbShare.completionHandler = {
result in
switch result {
case SLComposeViewControllerResult.Cancelled:
//Code to deal with it being cancelled
break
case SLComposeViewControllerResult.Done:
//Code here to deal with it being completed
break
}
}
refrenceViewController.presentViewController(fbShare, animated: true, completion: nil)
} else {
//open safari and post it there
}
I used the following code to post videos to facebook. You can use similar approach to post your text.
NSData *data = [NSData dataWithContentsOfURL:outputFileURL];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
data, #"video.mp4",
#"video/mp4", #"contentType",
caption, #"description",
nil];
/* make the API call */
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"/me/videos"
parameters:params
HTTPMethod:#"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
if(!error) {
DDLogDebug(#"result %#",result);
} else {
DDLogError(#"error description : %#",error.description);
[Helper showToast:[NSString stringWithFormat:#"Unable to share to Facebook : Error: %#",[error localizedDescription]] withDuration:1];
}
}];
of course before this you need to make sure that you already have the FBSDKAccess token granted. You can check the full documentation from facebook sdk
https://developers.facebook.com/docs/ios/graph

FBSession Error validating access token: Session does not match current stored session

I'm trying to use Facebook SDK in my application. My application is using Salesforce SDK to logging with Salesforce and the user can use Facebook to logging in my application.
From Salesforce can take the Facebook access token when the user logs in with Facebook. I use this access token to open a session with the object FBSession.
This is the code that I'm using to open a session:
NSArray *newPermission = [NSArray arrayWithObjects:#"user_friends",#"email", nil];
NSMutableDictionary *tokenInformationDictionary = [NSMutableDictionary new];
tokenInformationDictionary[#"com.facebook.sdk:TokenInformationExpirationDateKey"] = [NSDate dateWithTimeIntervalSinceNow: 3600];;
tokenInformationDictionary[#"com.facebook.sdk:TokenInformationRefreshDateKey"] = [NSDate date];
tokenInformationDictionary[#"com.facebook.sdk:TokenInformationTokenKey"] = fbAccessToken;
tokenInformationDictionary[#"com.facebook.sdk:TokenInformationPermissionsKey"] = newPermission;
tokenInformationDictionary[#"com.facebook.sdk:TokenInformationLoginTypeLoginKey"] = #0;
FBAccessTokenData *accesToken = [FBAccessTokenData createTokenFromDictionary: tokenInformationDictionary];
[[FBSession activeSession] openFromAccessTokenData:accesToken completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
}];
I'm trying to publish links and get my friends list.
To publish I use this code:
NSDictionary *params = #{
#"name" : [NSString stringWithFormat:NSLocalizedString(#"FBNameFormat", nil), [dicRecord objectForKey:#"Name"], [[dicRecord objectForKey:#"Store__r"] objectForKey:#"Name"]],
#"caption" : [NSString stringWithFormat:NSLocalizedString(#"FBCaptionFormat", nil), [dicRecord objectForKey:#"Name"], [[dicRecord objectForKey:#"Store__r"] objectForKey:#"Name"]],
#"description" : NSLocalizedString(#"FBDescription", nil), //#"Welcome to iOS world",
#"picture" : [dicRecord objectForKey:#"Image__c"],
#"link" : [NSString stringWithFormat:NSLocalizedString(#"FBDishUrl", nil), [dicRecord objectForKey:#"Id"]]//a00w000000V0TK9",
};
// Invoke the dialog
[FBWebDialogs presentFeedDialogModallyWithSession:nil parameters:params handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
NSLog(#"Error publishing story.");
//[self.indicator stopAnimating];
} else if (result == FBWebDialogResultDialogCompleted){
if ([isSuggested isEqual:[NSNumber numberWithInt:-1]]){
NSMutableDictionary *diccionario = [[NSMutableDictionary alloc] init];
}
}
}];
1)
That only works if I close and open again my apps, using
[FBSession.activeSession closeAndClearTokenInformation];
in completionHandler of openFromAccessTokenData.
Is there a way to make this work without having to close and re-open my app?
2)
When I try to get my Friend list using this code:
FBRequest *reqMyFriends = [FBRequest requestForMyFriends];
reqMyFriends.session = FBSession.activeSession;
[reqMyFriends startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary* result,NSError *error) {
if (!error){
NSArray* friends = [result objectForKey:#"data"];
}
}];
I get this error:
error =
{
code = 190;
"error_subcode" = 460;
message = "Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.";
type = OAuthException;
};
code = 400;
Why do I get this error?

How to post location with image to facebook in IOS?

I am trying to share location along with image to facebook. I have successfully shared image but unable to share location. Below is my code of sharing image.
UIImage *facebookImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#",imagesURL,str]]]];
NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
[params setObject:#"New Happening created on the HappenShare mobile app." forKey:#"message"];
[params setObject:facebookImage forKey:#"picture"];
[FBRequestConnection startWithGraphPath:#"me/photos" parameters:params HTTPMethod:#"POST" completionHandler:^(FBRequestConnection *connection,id result,NSError *error)
{
if (error)
{
NSLog(#"error : %#",error);
}
else
{
NSLog(#"Result : %#",result);
}
}];
Now for sharing location what parameter should I add in above code. I am attaching an image also to understand better that how the shared location will look like.Below image shows that how the image with text will indicate a location into map. Please suggest me a solution for that.
Along with "message" and you also need "place" ID to post as param.
Request for a "publish_actions" so that you can post a place/location.
Below is the code i've used:
NSMutableDictionary *params = [NSMutableDictionary dictionary];
[params setObject:#"Hello World" forKey:#"message"];
[params setObject:#"110503255682430"/*sample place id*/ forKey:#"place"];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"/me/feed" parameters:params HTTPMethod:#"POST"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSLog(#"result %#",result);
NSLog(#"error %#",error);
}];
You can also check this with the "administrator/tester" accounts given in Developer page -> your app -> Roles.
Use Graph explorer for better practice:
https://developers.facebook.com/tools/explorer/108895529478793?method=POST&path=me%2Ffeed%3F&version=v2.5&message=Hello%20world&place=110503255682430
Below code may help you in getting place id near your location:
NSMutableDictionary *params2 = [NSMutableDictionary dictionaryWithCapacity:4L];
[params2 setObject:[NSString stringWithFormat:#"%#,%#",YourLocation latitude,YourLocation longitude] forKey:#"center"]; //Hard code coordinates for test
[params2 setObject:#"place" forKey:#"type"];
[params2 setObject:#"100"/*meters*/ forKey:#"distance"];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"/search" parameters:params2 HTTPMethod:#"GET"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSLog(#"RESPONSE!!! /search");
}];
OR
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"/search?type=place&center=YourLocationLat,YourLocationLong&distance=500" parameters:nil HTTPMethod:#"GET"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSLog(#"result %#",result);
}];
Hope it helps you..
Swift 3.2 version of #Satish A answer.
func getPlaceId() {
let locManager = CLLocationManager()
locManager.requestWhenInUseAuthorization()
var currentLocation = CLLocation()
if( CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
CLLocationManager.authorizationStatus() == .authorizedAlways) {
currentLocation = locManager.location!
let param = ["center":"\(currentLocation.coordinate.latitude),\(currentLocation.coordinate.longitude)","type":"place","distance":"100"]
FBSDKGraphRequest(graphPath: "/search", parameters: param).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil) {
guard let data = result as? NSDictionary else {
return
}
guard let arrPlaceIDs = data.value(forKey: "data") as? [NSDictionary] else {
return
}
guard let firstPlace = arrPlaceIDs.first else {
return
}
//First facebook place id.
print(firstPlace.value(forKey: "id") as! String)
} else {
print(error?.localizedDescription ?? "error")
}
})
}
}
For Facebook sharing with attaching placeId
let photo = Photo(image: img, userGenerated: true)
var content = PhotoShareContent()
content.photos = [photo]
content.placeId = id //Facebook placeId
let sharer = GraphSharer(content: content)
sharer.failsOnInvalidData = true
do {
try sharer.share()
} catch {
print("errorrrr")
}
sharer.completion = { FBresult in
switch FBresult {
case .failed(let error):
print(error)
break
case .success(_):
//code
break
default:
break
}
}
You need to set the place (which is actually a Page ID) field within the POST request on /me/photos.
See https://developers.facebook.com/docs/graph-api/reference/v2.0/user/photos/#publish
On iOS, you can use the PlacePicker UI component of the FB iOS SDK for that, as described here: https://developers.facebook.com/docs/ios/ui-controls#placepicker

Set the coordinate parameter for facebook graph checkins

I am implementing the Checkins Facebook Graph API using Facebook SDK. This is the code for Checkins
NSDictionary *dict=[NSDictionary dictionaryWithObjectsAndKeys:accsstoken,#"access_token",#"253651184683030",#"place",#"I m here in this place",#"message",#"30.893075018178,75.821777459326",#"coordinates", nil];
[FBRequestConnection startWithGraphPath:#"/me/checkins"
parameters:dict
HTTPMethod:#"POST"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSLog(#"Error...%#",error);
}];
When I tried this above code. It gives me following error:
error = {
code = 160;
message = "(#160) Invalid coordinates. Coordinates must contain at least latitude and longitude.";
type = OAuthException;
};
It gives the coordinates issue. Is there a different way to pass the coordinates parameters? Please help me out of this issue.
As far as I know checkins are deprecated and you should use post with place parameter.
And here is the link. Facebook SDK reference
Edit: For people who too lazy to check the link, there is the sample code from Facebook.
// Create an object
NSMutableDictionary<FBOpenGraphObject> *restaurant = [FBGraphObject openGraphObjectForPost];
// specify that this Open Graph object will be posted to Facebook
restaurant.provisionedForPost = YES;
// Add the standard object properties
restaurant[#"og"] = #{ #"title":#"Restaurant Name", #"type":#"restaurant.restaurant", #"description":#"a description", #"image":image };
// Add the properties restaurant inherits from place
restaurant[#"place"] = #{ #"location" : #{ #"longitude": #"-58.381667", #"latitude":#"-34.603333"} };
// Add the properties particular to the type restaurant.restaurant
restaurant[#"restaurant"] = #{#"category": #[#"Mexican"],
#"contact_info": #{#"street_address": #"123 Some st",
#"locality": #"Menlo Park",
#"region": #"CA",
#"phone_number": #"555-555-555",
#"website": #"http://www.example.com"}};
// Make the Graph API request to post the object
FBRequest *request = [FBRequest requestForPostWithGraphPath:#"me/objects/restaurant.restaurant"
graphObject:#{#"object":restaurant}];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Sucess! Include your code to handle the results here
NSLog(#"result: %#", result);
_objectID = [result objectForKey:#"id"];
alertTitle = #"Object successfully created";
alertText = [NSString stringWithFormat:#"An object with id %# has been created", _objectID];
[[[UIAlertView alloc] initWithTitle:alertTitle
message:alertText
delegate:self
cancelButtonTitle:#"OK!"
otherButtonTitles:nil] show];
} else {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
}
}];
Checkins have been deprecated in favor of attaching place information to posts, or tagging places in Open Graph stories.
You can refer here
https://developers.facebook.com/docs/graph-api/reference/user/checkins/

Facebook Request Dialog for mobile - filtering users

I'm using request dialog in mobile app. Reading
https://developers.facebook.com/docs/reference/dialogs/requests/
I've found that
Note: the filters option is disabled on mobile dialogs and will not affect the set of users that appear in the dialog.
Unfortunately I need to show only friends with app installed in one dialog, and rest in the other. Is there any reasonable way to filter users like this while still using FB request dialog?
You could take a look at the Hackbook sample app, packaged with the SDK to show you how to do this, but in essence you have to create an API call to get, say users with the app installed and pass this to a parameter called "suggestions".
- (void)sendRequest:(NSArray *) targeted {
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"It's your turn, quit slacking.", #"message",
nil];
// Filter and only show targeted friends
if (targeted != nil && [targeted count] > 0) {
NSString *selectIDsStr = [targeted componentsJoinedByString:#","];
[params setObject:selectIDsStr forKey:#"suggestions"];
}
[self.facebook dialog:#"apprequests"
andParams:params
andDelegate:self];
}
- (void) sendToAppUsers {
FBRequest *appUsersRequest = [[FBRequest alloc]
initWithSession:FBSession.activeSession
restMethod:#"friends.getAppUsers"
parameters:nil
HTTPMethod:#"GET"];
FBRequestConnection *appUsersConnection = [[FBRequestConnection alloc] init];
[appUsersConnection
addRequest:appUsersRequest
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// Process the results
NSMutableArray *friendsWithApp = [[NSMutableArray alloc] init];
// Many results
if ([result isKindOfClass:[NSArray class]]) {
[friendsWithApp addObjectsFromArray:result];
} else if ([result isKindOfClass:[NSDecimalNumber class]]) {
[friendsWithApp addObject: [result stringValue]];
}
// User has friends that pass this filter
if ([friendsWithApp count] > 0) {
[self sendRequest:friendsWithApp];
}
}];
[appUsersConnection start];
}

Resources