Not see image after shared article to Facebook with FBSDKShareOpenGraphObject - objective-c

I try to shared image to Facebook and I need that the app name was be in the shared post in Facebook
this is the code :
FBSDKSharePhoto *photo = [[FBSDKSharePhoto alloc] init];
UIImage *image1 = [GeneralMethods imageConvertToSizeWithImage:postImageView.image scaledToWidth:300];
photo.image = [UIImage imageNamed:#"VImage.png"];
photo.userGenerated = YES;
NSDictionary *properties = #{
#"og:type": #"article",
#"og:title": #"new item",
#"og:description": #"bla bla",
// #"og:image": #[photo],
};
FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];
// [object setPhoto:photo forKey:#"og:image"];
// Create an action
FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init];
action.actionType = #"news.publishes";
[action setObject:object forKey:#"article"];
// Add the photo to the action. Actions
// can take an array of images.
[action setArray:#[photo] forKey:#"image"];
// Create the content
FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init];
content.action = action;
content.previewPropertyName = #"article";
[FBSDKShareDialog showFromViewController:ParetDelaget withContent:content delegate:self];
this is Facebook preview page with the image i add:
this is the post in my Facebook wall without image :
whats I do wrong ?

Uncomment this line:
// #"og:image": #[photo],
And comment this one:
[action setArray:#[photo] forKey:#"image"];
Like this you will have both image, title and description showing.
A little remark: the photo object must be a string URL
In my case, here is the resulting code:
// Create an object
NSDictionary *properties = #{
#"og:type": #"article",
#"og:url": #"https://the_link_you_want.com",
#"og:title": #"your title",
#"og:description": #"your description",
#"og:image": #"http://url_to_your_image"
};
FBSDKShareOpenGraphObject *object = [FBSDKShareOpenGraphObject objectWithProperties:properties];
// Create an action
FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init];
action.actionType = #"news.publishes";
[action setObject:object forKey:#"article"];
// Create the content
FBSDKShareOpenGraphContent *content = [[FBSDKShareOpenGraphContent alloc] init];
content.action = action;
content.previewPropertyName = #"article";
FBSDKShareDialog *shareDialog = [[FBSDKShareDialog alloc] init];
shareDialog.fromViewController = self;
shareDialog.shareContent = content;
[shareDialog show];
if (![shareDialog canShow]) {
// update the app UI accordingly
}
NSError *error;
if (![shareDialog validateWithError:&error]) {
NSLog(#"FB Error: %#", error);
}
Hope that helps

Related

How to share HashTag Text with Video On Facebook in IOS?

I'm sharing the video on Facebook (Without the SLComposer) from my IOS App. it will send successfully but I want To add the HashTag Text With it. Im Trying it But It will not get add shared with the video (only video get shared ).
FBSDKShareVideo *ShareVideo = [FBSDKShareVideo videoWithVideoURL:appDelegateObj.finalVideoUrl];
ShareVideo.videoURL = appDelegateObj.finalVideoUrl;
FBSDKShareVideoContent *ShareContnt = [[FBSDKShareVideoContent alloc] init];
ShareContnt.video = ShareVideo;
ShareContnt.hashtag = [FBSDKHashtag hashtagWithString:[NSString stringWithFormat:#"%#",#"We are #sharing this #video for the #testing of #video and the #HashTag Text"]];
[FBSDKShareAPI shareWithContent:ShareContnt delegate:self];
Please Help me for this issues ?
100% Working
I got the ANS Of these...
//Using these code we only share can't send the text / Title or name of video...
-(void)facbookSharng
{
NSLog(#"Permission for sharing..%#",[FBSDKAccessToken currentAccessToken].permissions);
if ([[FBSDKAccessToken currentAccessToken] hasGranted:#"contact_email"])
{
FBSDKShareVideo *ShareVideo = [FBSDKShareVideo videoWithVideoURL:appDelegateObj.finalVideoUrl];
ShareVideo.videoURL = appDelegateObj.finalVideoUrl;
FBSDKShareVideoContent *ShareContnt = [[FBSDKShareVideoContent alloc] init];
ShareContnt.video = ShareVideo;
[FBSDKShareAPI shareWithContent:ShareContnt delegate:self]
// write the deleate methdo for post ID..
}
}
//But for these Facebook gives another way,
NSLog(#"Permission for sharing..%#",[FBSDKAccessToken currentAccessToken].permissions);
if ([[FBSDKAccessToken currentAccessToken] hasGranted:#"contact_email"])
{
NSData *videoData = [NSData dataWithContentsOfURL:appDelegateObj.finalVideoUrl];
NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:3L];
[params setObject:videoData forKey:#"video_filename.MOV"];
[params setObject:#"Title for this post." forKey:#"title"];
[params setObject:#"#Description for this post." forKey:#"description"];
[[[FBSDKGraphRequest alloc] initWithGraphPath:#"/me/videos" parameters:params HTTPMethod:#"POST"]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
//video posted
NSLog(#"Facebook sharing completed %#:",result);
strFbSocialPostId = [result valueForKey:#"id"];//post ID
}
}];
}

Is there an example code for corespotlight search feature - iOS 9 API?

Is there an example code for corespotlight search feature - iOS 9 API? Really appreciate if can look at sample code to implement/test.
Create a new iOS project and add CoreSpotlight and MobileCoreServices framework to your project.
Create the actual CSSearchableItem and associating the uniqueIdentifier, domainIdentifier and the attributeSet. Finally index the CSSearchableItem using [[CSSearchableIndex defaultSearchableIndex]...] as show below.
OK!Test the index!
CSSearchableItemAttributeSet *attributeSet;
attributeSet = [[CSSearchableItemAttributeSet alloc]
initWithItemContentType:(NSString *)kUTTypeImage];
attributeSet.title = #"My First Spotlight Search";
attributeSet.contentDescription = #"This is my first spotlight Search";
attributeSet.keywords = #[#"Hello", #"Welcome",#"Spotlight"];
UIImage *image = [UIImage imageNamed:#"searchIcon.png"];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
attributeSet.thumbnailData = imageData;
CSSearchableItem *item = [[CSSearchableItem alloc]
initWithUniqueIdentifier:#"com.deeplink"
domainIdentifier:#"spotlight.sample"
attributeSet:attributeSet];
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:#[item]
completionHandler: ^(NSError * __nullable error) {
if (!error)
NSLog(#"Search item indexed");
}];
Note: kUTTypeImage requires that you import the MobileCoreServices framework.
To complete the spotlight search functionality, once you have implemented mayqiyue's answer, you'll be able to see the results in the search but on selection of the result simply your app would open not the related view with related content.
In order to do so, go to your AppDelegate.m and add the following method.
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
//check if your activity has type search action(i.e. coming from spotlight search)
if ([userActivity.activityType isEqualToString:CSSearchableItemActionType ] == YES) {
//the identifier you'll use to open specific views and the content in those views.
NSString * identifierPath = [NSString stringWithFormat:#"%#",[userActivity.userInfo objectForKey:CSSearchableItemActivityIdentifier]];
if (identifierPath != nil) {
// go to YOUR VIEWCONTROLLER
// use notifications or whatever you want to do so
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
MyViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:#"MyViewController"];
// this notification must be registered in MyViewController
[[NSNotificationCenter defaultCenter] postNotificationName:#"OpenMyViewController" object: myViewController userInfo:nil];
return YES;
}
}
return NO;
}
Make sure to import in AppDelegate.m :
#import <MobileCoreServices/MobileCoreServices.h>
#import <CoreSpotlight/CoreSpotlight.h>
UPDATE for Swift 2.1
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
if #available(iOS 9.0, *) {
if userActivity.activityType == CSSearchableItemActionType {
//the identifier you'll use to open specific views and the content in those views.
let dict = userActivity.userInfo! as NSDictionary
let identifierPath = dict.objectForKey(CSSearchableItemActivityIdentifier) as! String
if identifierPath.characters.count > 0 {
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let mvc: MyViewController = storyboard.instantiateViewControllerWithIdentifier("MyViewController") as! MyViewController
NSNotificationCenter.defaultCenter().postNotificationName("OpenMyViewController", object: mvc, userInfo: nil)
}
return true
}
} else {
// Fallback on earlier versions
return false
}
return false
}
Make sure to import in AppDelegate.swift :
import CoreSpotlight
import MobileCoreServices
I am using similar implementation as mentioned by #mayqiyue but I am also checking the existence of the item variable for backwards compatibility with iOS 8.
- (void)setupCoreSpotlightSearch
{
CSSearchableItemAttributeSet *attibuteSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(__bridge NSString *)kUTTypeImage];
attibuteSet.title = NSLocalizedString(#"Be happy!", #"Be happy!");
attibuteSet.contentDescription = #"Just like that";
attibuteSet.keywords = #[#"example", #"stackoverflow", #"beer"];
UIImage *image = [UIImage imageNamed:#"Image"];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
attibuteSet.thumbnailData = imageData;
CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:#"1"
domainIdentifier:#"album-1"
attributeSet:attibuteSet];
if (item) {
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:#[item] completionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(#"Search item indexed");
}
}];
}
}
To handle the tap on the search item from Spotlight you need to implement following method in your AppDelegate:
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
if ([userActivity.activityType isEqualToString:CSSearchableItemActionType]) {
NSString *uniqueIdentifier = userActivity.userInfo[CSSearchableItemActivityIdentifier];
// Handle 'uniqueIdentifier'
NSLog(#"uniqueIdentifier: %#", uniqueIdentifier);
}
return YES;
}
Write in your main controller Class
-(void)storeValueForSpotligtSearch {
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
// **Your Model Array that Contain Data Like attributes Make, Model, Variant and Year and Images**
for (MyCatalogeModel *myCatalogeModelObj in yourDataContainer) {
NSMutableArray *arrKeywords = [[NSMutableArray alloc] initWithObjects: myCatalogeModelObj.year, myCatalogeModelObj.make, myCatalogeModelObj.model, myCatalogeModelObj.variant, nil];
NSString *strIdentifier = [NSString stringWithFormat:#"%#.%#",bundleIdentifier, myCatalogeModelObj.carId];
self.userActivity = [[NSUserActivity alloc]initWithActivityType:strIdentifier];
self.userActivity.title = myCatalogeModelObj.year;
self.userActivity.title = myCatalogeModelObj.make;
self.userActivity.title = myCatalogeModelObj.model;
self.userActivity.title = myCatalogeModelObj.variant;
self.userActivity.eligibleForSearch = YES;
self.userActivity.eligibleForPublicIndexing = YES;
self.userActivity.eligibleForHandoff = YES;
CSSearchableItemAttributeSet * attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeJSON];
attributeSet.title = myCatalogeModelObj.make;
attributeSet.thumbnailData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[myCatalogeModelObj.imageArray objectAtIndex:0]]];
attributeSet.contentDescription = [NSString stringWithFormat:#"%# %# %# %#", myCatalogeModelObj.year, myCatalogeModelObj.make, myCatalogeModelObj.model, myCatalogeModelObj.variant];
attributeSet.keywords = arrKeywords;
CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:strIdentifier domainIdentifier:#"spotlight.CARS24ChannelPartnerapp" attributeSet:attributeSet];
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:#[item] completionHandler: ^(NSError * __nullable error) {
}];
self.userActivity.contentAttributeSet = attributeSet;
[self.userActivity becomeCurrent];
[self updateUserActivityState:self.userActivity];
}
}
Write in App Delegate
-(BOOL)application:(nonnull UIApplication *) application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * __nullable))restorationHandler {
#try {
NSString *strIdentifier;
NSNumber *numScreenId;
NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
NSLog(#"Activity = %#",userActivity.userInfo);
if (userActivity.userInfo[#"vc"]) {
numScreenId = userActivity.userInfo[#"vc"];
}
else{
strIdentifier = [userActivity.userInfo objectForKey:#"kCSSearchableItemActivityIdentifier"];
NSLog(#"strIdentifier : %#",strIdentifier);
NSArray *arr = [strIdentifier componentsSeparatedByString:#"."];
NSString *strScreenId = [arr objectAtIndex:3];
NSLog(#"ID -= %#",strScreenId);
**// On Click in Spotlight search item move your particular view.**
[self moveToParticular:[strScreenId intValue]];
numScreenId = [numFormatter numberFromString:strScreenId];
}
}
#catch (NSException *exception) {}
return YES;
}
let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeImage as String)
attributeSet.title = "Searchable Item"
attributeSet.contentDescription = "Code for creating searchable item"
attributeSet.keywords = ["Item","Searchable","Imagine"]
attributeSet.thumbnailURL = NSURL(string: "https://blog.imagine.com/")
let searchableItem = CSSearchableItem(uniqueIdentifier: "com.imagine.objectA", domainIdentifier: "spotlight.search", attributeSet: attributeSet)
CSSearchableIndex.defaultSearchableIndex().indexSearchableItems([searchableItem]) {_ in}

Cocoa [[NSWorkspace sharedWorkspace] iconForFile:filePath caused memory leaks

I am creating a cocoa application where i need to find out the icon images of file/directory. I am using this for getting icon image form the given path.
NSImage *image = [[NSWorkspace sharedWorkspace] iconForFile:path];
This method is called recessively in whole application. The allocated memory of the application is increased as much i use my app. Using instruments when i look for the memory leaks, i find out that the above method is responsible for the 100% memory leaks.
How can i remove this memory leaks, or is their any other way why which i can get icon image and memory will not be a problem.
Please help me someone.
Thanks
Edited:
This is the method from which i am calling this method.
-(WEFile *)fileAtPath:(NSString *)filePath
{
WEFile *file = [[WEFile alloc] init];
file.fIconImage = [workSpace iconForFile:filePath];
file.Name = [fileManager displayNameAtPath:filePath];
file.type = [workSpace localizedDescriptionForType:[workSpace typeOfFile:filePath error:&error]];
NSDictionary *detailDict = [fileManager attributesOfItemAtPath:filePath error:&error];
file.modificationDate = [ Utility createDateFormat:[detailDict objectForKey:NSFileModificationDate]];
file.creationDate = [ Utility createDateFormat:[detailDict objectForKey:NSFileCreationDate]];
file.Size = [[detailDict objectForKey:NSFileSize] integerValue];
file.fPath = filePath;
NSDictionary *metaDict = [self metadataForFileAtPath:filePath];
file.addedDate = [ Utility createDateFormat:[metaDict objectForKey:#"kMDItemDateAdded"]];
file.lastOpenedDate = [ Utility createDateFormat:[metaDict objectForKey:#"kMDItemLastUsedDate"]];
return [file autorelease];
}
The method fileAtPath is called recursively from another and the WEFile class objects are stored in a array. and display in a tableview.
EDIT 2: Here is the code from where i call fileAtPath method. And this method directoryAtPath is called when table selection passing path of directory as a parameter.
-(WEDirectory *)directoryAtPath:(NSString *)dirPath
{
WEDirectory *dir = [[[WEDirectory alloc] init] autorelease];
NSArray *childArray = [self getContentsWithinDirectory:dirPath];
if (childArray && [childArray count]>0)
{
for (int i = 0; i<[childArray count]; i++)
{
NSURL *fileURL = [childArray objectAtIndex:i];
NSString *filePath = [self getPathFromURL:fileURL];
filePath = [filePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
BOOL isDir;
BOOL success = [fileManager fileExistsAtPath:filePath isDirectory:&isDir];
if (!success)
{
continue;
}
if(isDir)
{
WEDirectory *childDir = [[WEDirectory alloc] init] ;
childDir.dIconImage = [workSpace iconForFile:filePath];
childDir.Name = [fileManager displayNameAtPath:filePath];
childDir.type = [workSpace localizedDescriptionForType:[workSpace typeOfFile:dirPath error:&error]];
NSDictionary *detailDict = [fileManager attributesOfItemAtPath:filePath error:&error];
childDir.modificationDate = [ Utility createDateFormat:[detailDict objectForKey:NSFileModificationDate]];
childDir.creationDate = [ Utility createDateFormat:[detailDict objectForKey:NSFileCreationDate]];
childDir.Size = [[detailDict objectForKey:NSFileSize]integerValue];
childDir.dPath = filePath;
[dir.childsArray addObject:childDir];
[childDir release];
}
else
{
WEFile *childFile = [self fileAtPath:filePath];
[dir.childsArray addObject:childFile];
}
}
}
return dir ;
}
This works without causing memory leaks in my code - checked it with Leaks/Allocations:
GAppSettings.h your WEFile-class
NSImage *gAppIcon;
#property (readwrite, retain) NSImage *gAppIcon;
*.m
#synthesize gAppIcon;
in ->init
gAppIcon = nil;
in -> dealloc
[ gAppIcon release];
I am also using for storing and restoring
->initWithCoder
self.gAppIcon = [ decoder decodeObjectForKey:#"gAppIcon"];
->encodeWithCoder
[ coder encodeObject: [ self gAppIcon] forKey: #"gAppIcon"];
and
- ( id ) copyWithZone: ( NSZone *)zone
{
return self;
}
The icon is loaded frequently in another class:
GAppSettings *appSettings = [ [ [GAppSettings alloc] init] autorelease];
...
NSImage *appIcon = [ [ NSWorkspace sharedWorkspace] iconForFile:completeAppPath];
[ appSettings setGAppIcon:appIcon];
...
return appSettings;
Then added to an array...

Change a Property for All Objects in an NSMutableArray

I have an NSMutableArray with 9 objects. Those objects have many properties, like questionName, questionWhatRow, etc.
I want to be able to change one of those properties for All of the objects in the NSMutableArray.
Here is my NSMutableArray Class.
-(id) init
{
self = [super init];
if (self)
{
self.questionsArray = [[NSMutableArray alloc] init];
Question *newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What is the name of the girl who has to fetch water for her family every day?";
newQuestion.questionRowName = #"Question 1";
newQuestion.questionAnswer = #"Nya";
newQuestion.questionHint = #"Maybe if you read the book you would know";
newQuestion.questionWhatRow = #"Nya";
newQuestion.questionCompleteOrNot = #"No";
newQuestion.pointForQuestion = 1;
[self.questionsArray addObject:newQuestion];
newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What is Nya's sister's name?";
newQuestion.questionRowName = #"Question 2";
newQuestion.questionAnswer = #"Akeer";
newQuestion.questionHint = #"Maybe if you read the book you would know";
newQuestion.questionWhatRow = #"Nya";
newQuestion.questionCompleteOrNot = #"No";
newQuestion.pointForQuestion = 1;
[self.questionsArray addObject:newQuestion];
newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What people is Nya's mother scared of when her father and sons go hunting?";
newQuestion.questionRowName = #"Question 3";
newQuestion.questionAnswer = #"Dinka";
newQuestion.questionHint = #"Maybe if you read the book you would know";
newQuestion.questionWhatRow = #"Nya";
newQuestion.questionCompleteOrNot = #"No";
newQuestion.pointForQuestion = 1;
[self.questionsArray addObject:newQuestion];
newQuestion = [[Question alloc] init];
newQuestion.questionName = #"What is Salva scared of when he is in the Akobo desert?";
newQuestion.questionRowName = #"Question 4";
newQuestion.questionAnswer = #"Lions";
newQuestion.questionHint = #"He is scared of an animal because it ate his friend Marial";
newQuestion = nil;
}
return self;
}
-(NSUInteger)count
{
return questionsArray.count;
}
- (Question *)questionAtIndex:(NSUInteger)index
{
return [questionsArray objectAtIndex:index];
}
Now, I have another class called ScoreViewController, and I want to be able to change the property, questionCompleteOrNot of the NSMutableArray questionsArray for all objects/questions to #"No".
My ScoreView has a button to Reset, but I don't know what to put in it to change all questionCompleteOrNot properties of the questionsArray to #"No".
Sorry for the long question, I was trying to be very specific.
Edit
Here is my DetailView for a tableView.
if ([[selectedQuestion questionCompleteOrNot] isEqualToString:#"No"])
{
if ([[selectedQuestion questionAnswer] caseInsensitiveCompare:answerField.text] == NSOrderedSame)
{
// Show the correct label
[correctLabel setHidden:NO];
correctLabel.text = #"Correct!";
correctLabel.textColor = [UIColor greenColor];
}
else
{
// Show the incorrect label
[correctLabel setHidden:NO];
correctLabel.text = #"Incorrect";
correctLabel.textColor = [UIColor redColor];
[incorrectPlayer play];
[[selectedQuestion questionCompleteOrNot] isEqualToString:#"Yes"];
}
// Erase the text in the answerField
answerField.text = #"";
}
if ([[selectedQuestion questionCompleteOrNot] isEqualToString:#"Yes"])
{
UIAlertView *error = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"You already answered this question. Please click the reset button on the score view to restart."
delegate:self
cancelButtonTitle:#"Okay!"
otherButtonTitles:nil];
[error show];
answerField.text = #"";
}
selectedQuestion.questionCompleteOrNot = #"Yes";
correctLabel.text = #"";
NSLog(#"Selected question's questionCompleteOrNot is %#", [selectedQuestion questionCompleteOrNot]);
You can use NSArray's makeObjectsPerformSelector:withObject:, like so:
[questionsArray makeObjectsPerformSelector:#selector(setQuestionCompleteOrNot:) withObject:#"No"];

Is there quick way to check user access using ALAssetsLibrary?

I think this is a really bad way to check user access to the resources.
Is there better way to get user access?
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// create library
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
accessGiven = YES;
return ;
};
void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {
accessGiven = NO;
return;
};
// create 2 blocks
NSURL *url = [[NSURL alloc] initWithString:#" "];
[library assetForURL:url resultBlock:resultblock failureBlock:assetGroupEnumberatorFailure];
// use empty url to check acces..
[library release];
iOS 6.0 has better way to do that.
[ALAssetsLibrary authorizationStatus];
Method Description
Authorization Status Enum