When I am sending a panorama image (made with default panorama mode of my iPhone) to my iOS Share extension, hasItemConformingToTypeIdentifier tells me that there is indeed an image sent, however loadItemForTypeIdentifier does not return anything.I don't have any completeRequestReturningItems on the whole flow which could prevent the loadItemForTypeIdentifier to proceed until the end. This works however fine with a normal image.
How come panorama images give issues ?
for (NSExtensionItem *item in self.extensionContext.inputItems)
{
for (NSItemProvider *itemProvider in item.attachments)
{
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage])
{
NSLog(#"Found item:%#",item); --> Is displayed
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error)
{
NSLog(#"Item delivered"); --> Is never displayed for panorama pictures
if(image) {
selectedImage=image;
mediaType=1;
NSLog(#"Image found !!");
imageFound = YES;
}
}];
break;
}
}
}
Related
I am creating an app with Share Extension. The sharing works like a charm on Chrome, Safari, and many more, but EXCEPT for PocketApp. If I try to share a link from PocketApp to my ShareExtension App, the hasItemConformingToTypeIdentifier(kUTTypeURL) function returns true. But during the loadItemForTypeIdentifier, the completionHandler ALWAYS RETURNS an ERROR.
Any thought about this?
- (void)didSelectPost{
inputItem = self.extensionContext.inputItems.firstObject;
for ( NSItemProvider * itemProvider in inputItem.attachments )
{
if ([itemProvider hasItemConformingToTypeIdentifier:(__bridge NSString *)kUTTypeURL])
{
NSLog(#"Attachment is a URL");
[itemProvider loadItemForTypeIdentifier:(__bridge NSString *)kUTTypeURL options:nil completionHandler:^(NSURL *url, NSError *error)
{
if (error)
{
NSLog(#"Error occured");
}
else
{
NSLog(#"Success occured");
}
}
}
}
I have added a table view, and I am display image in the cells. I have also added this code:
So that the cells resize depending on the image.
When I launch my app though, I get this : [![enter image description here][1]][1]
And the images do not load untill I start scrolling...If I scroll down half the page then go back to the top, I get this: Which is correct
[![enter image description here][2]][2]
Any ideas? I have researched on google and tried the odd solution for the older versions of Xcode, But nothing seems to work!
Here is the rest of my code from the TableViewController:
Image isn't loaded correctly in cellForRowAtIndexPath delegate method, you're (probably) downloading the image in the background, so cellForRowAtIndexPath is returned before image is ready.
Downloaded image is probably cached somewhere so next time it's loaded properly.
post.downloadImage() better have a callback closure to be called when image was downloaded, to assign the downloaded image into the proper cell.
Keep in mind that user may scroll this cell out of the screen before image is loaded, so you better use a unique id to abort downloaded image assignment if cell has already changed.
Here's an example for a method that downloads an image in the background, then assigns it to the cell -
+ (void)loadImage:(NSString *)imageUrl onComplete:(void(^)(UIImage *image, BOOL loaded, NSString *callIdentifier))callback callIdentifier:(NSString *)callIdentifier {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul), ^{
[self downloadPicture:url onComplete:^(UIImage *image, BOOL loaded) {
dispatch_sync(dispatch_get_main_queue(), ^{
callback(image, loaded, callIdentifier);
});
}];
});
callback([UIImage imageNamed:#"placeholder"], NO, callIdentifier);
}
+ (void)downloadPicture:(NSString *)url saveTo:(NSString *)filePath onComplete:(void (^)(UIImage *image, BOOL loaded))onComplete {
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url] options:NSDataReadingMappedAlways error:&error];
if (!error) {
UIImage *image = [UIImage imageWithData:data scale:GTUserPictureScale];
if (onComplete)
onComplete(image, YES);
} else {
NSLog(#"Error loading user picture: %#", [error description]);
if (onComplete)
onComplete([UIImage imageNamed:#"missing"], NO);
}
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ...
__weak MyClass *wself = self;
self.imageUrl = #"http://...";
[self loadImage:self.imageUrl onComplete:^(UIImage *image, BOOL loaded, NSString *callIdentifier) {
#synchronized(wself) {
if ([callIdentifier isEqualToString:wself.imageUrl]) {
if (loaded) {
wself.image = image;
}
} else
NSLog(#"Expired load image request for id %#", callIdentifier);
}
} callIdentifier:self.imageUrl];
// ...
}
I am sure this is trivial once someone kindly point me in the right direction so my apology for asking a silly question. However I have been searching for days I can't figure out what I am doing wrong.
Scenario: create a simple share extension that receives an image file
Problem: when I access the attachements, the handler is never called albeit I can see the "public.jpg" in the itemProvider but I can't see where the data would be?
What I have done:
1) defined NSExtensionActivationSupportsImageWithMaxCount = 1 as my only activation rule
2) added CoreMedia framework to the extension
3) added the same group to both app and app extension
4) made sure both have the group (1) in the entitlement
5) made sure both are using a certificate/app id with that group enabled
6) clean and rebuild several times to no avail.
The code:
- (void)didSelectPost {
/
for (NSExtensionItem *item in self.extensionContext.inputItems) {
for (NSItemProvider *itemProvider in item.attachments) {
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
I can hit this breakpoint --> [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error) {
but not this one --> photo = image;
}];
break;
}
}
}
.... and so on and so forth
You haven't posted your complete code but I suspect that you are calling completeRequestReturningItems:completionHandler: at the wrong location:
WRONG:
- (void)didSelectPost {
NSExtensionItem *item = self.extensionContext.inputItems.firstObject;
NSItemProvider *itemProvider = item.attachments.firstObject;
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage
options:nil
completionHandler:^(NSURL *url, NSError *error) {
// send the image
}];
}
// ↓ this is the wrong location ↓
[self.extensionContext completeRequestReturningItems:#[] completionHandler:nil];
}
The problem is that calling completeRequestReturningItems:completionHandler: immediately dismisses the ShareViewController and deallocates it. So the NSItemProvider that contains the image is also destroyed before it can access the image (because it loads its items asynchronously). In other words: the completion handler in which you send the image to your server is never called, because the whole shareViewController has already been deallocated.
To fix that problem you have to move the call to completeRequestReturningItems:completionHandler: to the end of the completion handler AFTER you send the image.
CORRECT:
- (void)didSelectPost {
NSExtensionItem *item = self.extensionContext.inputItems.firstObject;
NSItemProvider *itemProvider = item.attachments.firstObject;
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage
options:nil
completionHandler:^(NSURL *url, NSError *error) {
// send the image
[self.extensionContext completeRequestReturningItems:#[]
completionHandler:nil];
}];
}
}
I am fairly new to this field. Can any please help in sharing the in app screenshot to facebook. I have been trying to share screenshot using the [FBDialogs presentShareDialogWithParams] but then it says only FBLinkShareParams: only \"http\" or \"https\" schemes are supported for link thumbnails.
How can we share a in app screenshot of ios device on facebook ?
Hope this helps
-(void)FBshareScreenshot{
if ([FBDialogs canPresentShareDialogWithPhotos]) {
FBPhotoParams *params = [[FBPhotoParams alloc] init];
UIImage *screenshot = [self captureScreenshot]; //calling to capture screenshot
params.photos = #[screenshot];
[FBDialogs presentShareDialogWithPhotoParams:params
clientState:nil
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if(error) {
NSLog(#"Error publishing story = %#.", error);
NSLog(#"result = %#.", results);
} else if (results[#"completionGesture"] && [results[#"completionGesture"] isEqualToString:#"cancel"]) {
NSLog(#"User canceled photo publishing.");
} else {
NSLog(#"photo posted");
}
}];
}else {
//The user doesn't have the Facebook for iOS app installed, so we can't present the Share Dialog
/*Fallback: You have two options
1. Share the photo as a Custom Story using a "share a photo" Open Graph action, and publish it using API calls.
See our Custom Stories tutorial: https://developers.facebook.com/docs/ios/open-graph
2. Upload the photo making a requestForUploadPhoto
See the reference: https://developers.facebook.com/docs/reference/ios/current/class/FBRequest/#requestForUploadPhoto:
*/
}
}
-(UIImage *)captureScreenshot{
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *imageView = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// UIImageWriteToSavedPhotosAlbum(imageView, nil, nil, nil);
return imageView;
}
I am working on Game Center for iOS devices using the sandbox environment. I am trying to load the achievement images I set up in iTunes Connect.
I am using loadAchievementDescriptionWithConpletionHandler successfully.
The problem happens when I try to load the image using loadImageWithCompletionHandler.
[self.description loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
if (!error) {
self.achievementImage = image;
}
}];
The problem is both the UIImage and the error are nil.
It is due to the sandbox environment ? Am I missing something ?
Thanks
I can load the image successfully. It looks like my image format was wrong.
I have deleted the achievement and created a new one using a 512x512 72 dpi image.
Using loadAchievementDescriptionsWithCompletionHandler. I load all the achievementDescriptions from Game Center. Then, I use loadImageWithCompletionHandler to extract the image.
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) {
if (!error) {
for (GKAchievementDescription *achievementDescription in descriptions) {
[self.achievementDescriptionDictionary setObject:achievementDescription
forKey:achievementDescription.identifier];
[achievementDescription loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
if (!error) {
if (image) {
UIImage *achievementimage = image;
}
}
}];
}
}
}];