So I added some code to this to work on both ios 8 and 9(5s and ipad). Before the change the 5s would load the share dialog fairly quick while the ipad would crash the device. After adding the fix they both don't crash, but now the ipad displays the share dialog fairly quick while the 5s takes roughly ~1-2 mins to display it. Not sure why that might be, maybe I did something wrong with my change?
#import <Foundation/Foundation.h>
extern "C" {
void _shareText(const char *text, const char *imgUrl)
{
NSString * message = [NSString stringWithUTF8String:text];
NSString * urlAddress = [NSString stringWithUTF8String:imgUrl];
NSURL *url = [NSURL URLWithString:urlAddress];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
NSMutableArray *sharingItems = [NSMutableArray new];
if (text) {
[sharingItems addObject:message];
}
if (img) {
[sharingItems addObject:img];
}
UIViewController *qtController = [[UIApplication sharedApplication].keyWindow rootViewController];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
if ([activityController respondsToSelector:#selector(popoverPresentationController)] ){
[qtController presentViewController:activityController animated:YES completion:nil];
activityController.popoverPresentationController.sourceView = qtController.view;
}else{
[qtController presentViewController:activityController animated:YES completion:nil];
}
}
}
Update:
Unity Called function:
[DllImport("__Internal")]
private static extern void _shareText(string message, string imgUrl);
public static void InviteRequest(string message, string imgUrl)
{
#if UNITY_IOS
if (Application.platform != RuntimePlatform.OSXEditor)
{
_shareText(message, imgUrl);
}
#endif
}
Related
I'm trying to make a module for react-native using NYTPhotoViewer and asynchronous image downloading. It works, but first image never stops to animate loading when the other downloads and shows. Interesting, that if I swipe some images (2 and more), the first image will render. The code is here:
#import <NYTPhotoViewer/NYTPhotosViewController.h>
#import "NYTImageViewer.h"
#import "NYTExamplePhoto.h"
#interface NYTImageViewer () <NYTPhotosViewControllerDelegate>
#property (nonatomic) NSArray *photos;
#end
#implementation NYTImageViewer
RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(open:(NSArray *)urls)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *photos = addPhotos(urls);
NYTPhotosViewController *photosViewController = [[NYTPhotosViewController alloc] initWithPhotos:photos];
UIViewController *ctrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[ctrl presentViewController:photosViewController animated:TRUE completion: nil];
});
}
NSArray* addPhotos(NSArray *urls) {
NSMutableArray *photos = [NSMutableArray array];
for (int i = 0; i < [urls count]; i++) {
NYTExamplePhoto *photo = [[NYTExamplePhoto alloc] init];
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: urls[i]]];
if ( imageData == nil )
return;
dispatch_async(dispatch_get_main_queue(), ^{
photo.image = [UIImage imageWithData: imageData];
});
});
[photos addObject:photo];
}
return photos;
}
#end
How can I fix it?
You shouldn't/can't load that way from a remote URL, and with the dispatch_async it's generating the expected behavior:
NSData * _data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: urls[i]]];
You must use NSURLSession or NSURLConnection via asynchronous method for remote calls, and you'll have to handle recursion at the callback.
I am working on a xcode project in objective-c and i want a share button on my ios application to share things i watched a tutorial on youtube here's the link : https://www.youtube.com/watch?v=zkrOKN_OA_A
but when i run this code on iphone it works properly and when i run this code on ipad the xcode give's me this error :
int main(int argc, char * argv[]) {
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}}
I used this code :
- (IBAction)Share1:(id)sender {
UIImage *shareImage = [UIImage imageNamed:#"invoice_logo.png"];
NSArray *itemsToShare = #[shareImage];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
activityVC.excludedActivityTypes = #[];
[self presentViewController:activityVC animated:YES completion:nil];}
You are missing :
activityVC.excludedActivityTypes=#[UIActivityTypePostToFacebook,UIActivityTypePostToTwitter]// add your share types
look at the video you provided from 7:30 min
Try this:
UIImage *shareImage = [UIImage imageNamed:#"invoice_logo.png"];
NSArray *itemsToShare = #[shareImage];
UIActivityViewController *activityVC = [[UIActivityViewController alloc]
initWithActivityItems:itemsToShare applicationActivities:nil];
activityVC.popoverPresentationController.sourceView = self.view;
activityVC.popoverPresentationController.sourceRect =
CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height-50, 1.0, 1.0);
[self presentViewController:activityVC animated:YES completion:nil];
I’m building an article reading app for iPad. I have integrated a social sharing functionality which means user can share articles on Facebook, and google mail.
I’m using UIActivityViewController for sharing.
There is a bar button item,when user click on that UIActivityViewController opens.I updated Xcode 6
When I run on simulator it runs fine But I run on real device(iPad) with iOS 7,the app get crash on clicking on bar button item.
this is my code:
- (IBAction)ysshareAction:(id)sender
{
NSURL *linkURL = [NSURL URLWithString:_DetailModal1[4]];//article url
NSMutableAttributedString *stringText = [[NSMutableAttributedString alloc] initWithString:_DetailModal1[0]];//_DetailModal1[0] contain article title////
[stringText addAttribute:NSLinkAttributeName value:linkURL range:NSMakeRange(0, stringText.length)];
NSArray * itemsArray = #[[NSString stringWithFormat:#"%#",_DetailModal1[0]], [NSURL URLWithString:_DetailModal1[4]]];
NSArray * applicationActivities = nil;
UIActivityViewController * AVC = [[UIActivityViewController alloc] initWithActivityItems:itemsArray applicationActivities:applicationActivities];
AVC.popoverPresentationController.sourceView = _webView;
[self presentViewController:AVC animated:YES completion:nil];
[AVC setCompletionHandler:^(NSString *act, BOOL done)
{
if([act isEqualToString:UIActivityTypeMail]) {
ServiceMsg = #"Mail sent!";
} else if([act isEqualToString:UIActivityTypePostToTwitter]) {
ServiceMsg = #"Article Shared!";
} else if([act isEqualToString:UIActivityTypePostToFacebook]) {
ServiceMsg = #"Article Shared!";
} else if([act isEqualToString:UIActivityTypeMessage]) {
ServiceMsg = #"SMS sent!";
} else if([act isEqualToString:UIActivityTypeAddToReadingList]) {
ServiceMsg = #"Added to Reading List";
} else if([act isEqualToString:UIActivityTypeCopyToPasteboard]){
ServiceMsg = #"Copied Link";
}
if ( done )
{
UIAlertView *Alert = [[UIAlertView alloc] initWithTitle:ServiceMsg message:#"" delegate:nil cancelButtonTitle:#"ok" otherButtonTitles:nil];
[Alert show];
}
}];
}
Help is appreciated!
Following line is the issue
AVC.popoverPresentationController.sourceView = _webView;
You will have to put iOS8 condition in order popoverPresentationController is introduced for iOS 8 and later so you can not use it with iOS 7
For checking for iOS8 you can define a macro like found from here
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
And use it in following way.
NSURL *linkURL = [NSURL URLWithString:_DetailModal1[4]];//article url
NSMutableAttributedString *stringText = [[NSMutableAttributedString alloc] initWithString:_DetailModal1[0]];//_DetailModal1[0] contain article title////
[stringText addAttribute:NSLinkAttributeName value:linkURL range:NSMakeRange(0, stringText.length)];
NSArray * itemsArray = #[[NSString stringWithFormat:#"%#",_DetailModal1[0]], [NSURL URLWithString:_DetailModal1[4]]];
NSArray * applicationActivities = nil;
UIActivityViewController * AVC = [[UIActivityViewController alloc] initWithActivityItems:itemsArray applicationActivities:applicationActivities];
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"8.0")){
AVC.popoverPresentationController.sourceView = _webView;
}
[self presentViewController:AVC animated:YES completion:nil];
Refer this for more info about what has changed for UIActivityViewController in iOS8
A lot might argue that checking for existence of the class explicitly is better than checking a hard coded version number. UIPopoverPresentationController may be deprecated at some future point, or there might be a (future ?) device which does not support the class, like the iPhone never used to support UIPopoverController or UISplitViewController..
if ( NSClassFromString(#"UIPopoverPresentationController") ) {
AVC.popoverPresentationController.sourceView = _webView;
}
In Swift, You can use '?' instead checking OS version.
AVC.popoverPresentationController?.sourceView = _webView
I am using a UIActivityViewController in my app, and I am getting a EXC_BAD_ACCESS code=2 crash on iOS 6, but not iOS 7. Here is the code:
NSArray *activityItems;
NSString *shareText = [NSString stringWithFormat:NSLocalizedString(#"Listen to", nil), self.currentChannel.title, self.currentChannel.itunesUrl];
if (self.currentChannel.mediumThumbnailImage)
{
activityItems = #[shareText, self.currentChannel.mediumThumbnailImage];
}
else
{
activityItems = #[shareText];
}
UIActivityViewController *activityController = [[UIActivityViewController alloc]
initWithActivityItems:activityItems
applicationActivities:nil];
[activityController setCompletionHandler:^(NSString *activityType, BOOL completed) {
// once they have shared, check where they shared the content for analytics
if (completed)
{
NSString *actionName = nil;
NSString *socialName = nil;
if ([activityType isEqualToString:kMailActivity]) {
actionName = kSocialEmail;
socialName = kMail;
} else if ([activityType isEqualToString:kMessageActivity]) {
actionName = kSocialChat;
socialName = kMessage;
} else if ([activityType isEqualToString:kFacebookActivity] || [activityType isEqualToString:kTwitterActivity]) {
actionName = kSocialShare;
socialName = kFacebook;
}
if (actionName && socialName)
{
NSDictionary *data = #{kSocialName: socialName, kSocialContent: shareText};
if (data)
{
[ADBMobile trackAction:actionName data:data];
}
}
}
}];
if (activityController)
{
[activityController setExcludedActivityTypes:
#[UIActivityTypeAssignToContact,
UIActivityTypePrint,
UIActivityTypePostToWeibo,
UIActivityTypeSaveToCameraRoll,
UIActivityTypeAirDrop]];
[self presentViewController:activityController
animated:YES completion:nil];
}
I have used NSZombies to narrow down where the crash is happening, and it is happening when I call setExcludedActivityTypes: in iOS 6. I know that this error means that an object has been overreleased, and I am touching memory that doesn't belong to me. What I don't understand is why this crash is only occurring in iOS 6. Does anyone see something that could be causing this?
UIActivityTypeAirDrop is only available in iOS 7 and not in iOS 6.
You can check the availability of a constant like this:
if(&UIActivityTypeAirDrop) {
// UIActivityTypeAirDrop is available
} else {
// Its not available. Don't use it.
}
(I'm making this a community wiki, because I just copied the comment from user Larme above.)
I am dealing with FBProfilePictureView. I have tried following method and it works.
- (void)getUserImageFromFBView
{
UIImage *img = nil;
for (NSObject *obj in [self.profilePictureView subviews]) {
if ([obj isMemberOfClass:[UIImageView class]]) {
UIImageView *objImg = (UIImageView *)obj;
img = objImg.image;
break;
}
}
}
Here, I have to put a delay for calling this method, say 5.0f
Again in some cases image downloading is not get completed within this period.
Is there any possible way to check whether facebook profile image downloading is completed or not. Also image download delay occurs when user changes profile picture in facebook.
Any help is appreciated. Thanks in advance.
Instead of it Try :
- (void) getFBImage
{
NSString *facebookID = #"";
if (![_resultDictionary objectForKey:#"username"] && ![[_resultDictionary objectForKey:#"username"] isEqualToString:#""])
{
facebookID = [_resultDictionary objectForKey:#"username"];
}
else if ([_resultDictionary objectForKey:#"id"] && ![[_resultDictionary objectForKey:#"id"] isEqualToString:#""])
{
facebookID = [_resultDictionary objectForKey:#"id"];
}
if ([facebookID isEqualToString:#""])
{
return;
}
else
{
NSString *string=[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?width=105&height=109",facebookID];
NSURL *url = [NSURL URLWithString:string];
dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *imgData = [[NSData alloc] initWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
[_imgDisplay setImage:[UIImage imageWithData:imgData]];
});
});
}
}
//_imgDisplay is my UIImageView which display Facebook Profile image , _resultDictionary contain Facebook User Id or Username.
You could use a image downloader framework like SDWebImage and track if the image has been downloaded or not using the method
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
options:(SDWebImageDownloaderOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageDownloaderCompletedBlock)completedBlock;