Using a URL to share an image with iOS 6 and UIActivityViewController - image

I am using iOS 6's UIActivityViewController.
I would like to share an image that is not available locally on my iPhone, but that it is available on a remote URL.
NSString *textToShare = _eventoTitle;
UIImage *imageToShare = [UIImage imageNamed:_iconUrl];
NSURL *url = [NSURL URLWithString:_permalink];
NSArray *activityItems = [[NSArray alloc] initWithObjects:textToShare, imageToShare, url, nil];
Unfortunately, this is not working. What am I doing wrong?
I have also tried to use the AFNetworking library:
UIImage *imageToShare = [UIImage alloc];
[*imageToShare setImageWithURL:[NSURL URLWithString:_iconUrl]];
This is not working too.
_iconUrl is something like http://www.mysite.com/picture.png
Thank you, Francesco

Try with:
UIImage *imageToShare = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#", _iconUrl]]]];
Matteo

To use remote images, I implemented a UIActivityItemProvider subclass that downloads the image when requested by the UIActivityViewController. UIActivityViewController calls your UIActivityItemProvider on a background thread so at least it doesn't block the main UI. I use a synchronous call just like Matteo suggests inside my UIActivityItemProvider. However, it's really still not a great solution because it just delays when you have to go do the expensive download. UIActivityViewController doesn't request your data until the user picks one of the activity icons in the view controller. At that time, it calls the UIActivityItemProvider to get the data. So you get a delay at this time.

Related

NSBundle UIImage nil iOS 7 specific

I created a framework using the Xcode 6 Cocoa Touch Framework target feature.
When the framework is used in another app running on iOS 8, it works perfectly fine, loading images, picking up nibs-storyboards etc..
When I run the same app on an iOS 7 device, the code is picked up, view controllers are showing up, images that are set in the interface builder for the nib are showing up. But the images that are being set through code are not showing up.
The image is present in the app's contents (when I do a show package contents).
But its not getting picked up. Please see my code.
NSString *bundlePath = [NSString stringWithFormat:#"%#/Frameworks/TestFramework.framework", [[NSBundle mainBundle] bundlePath]];
NSBundle *frameworkBundle = [NSBundle bundleWithPath:bundlePath];
[frameworkBundle load];
NSString *imagePath = [NSString stringWithFormat:#"%#/Pic2.JPG", bundlePath];
UIImage *image = [UIImage imageNamed:imagePath];
NSLog(#"FrameworkBundle:%#", frameworkBundle);
NSLog(#"BundlePath:%#", bundlePath);
NSLog(#"ImagePath:%#",imagePath);
NSLog(#"Image:%#",image);
self.imageView3.image = image;
This is the output
2014-11-19 11:48:01.324 TestApp[95937:60b] FrameworkBundle:NSBundle </Users/nbkqkka/Library/Developer/CoreSimulator/Devices/A64CFDA9-EB0E-4B65-B119-A213CD500217/data/Applications/C942AA07-E416-48B3-AE96-C853DB349B64/TestApp.app/Frameworks/TestFramework.framework> (loaded)
2014-11-19 11:48:01.324 TestApp[95937:60b] BundlePath:/Users/nbkqkka/Library/Developer/CoreSimulator/Devices/A64CFDA9-EB0E-4B65-B119-A213CD500217/data/Applications/C942AA07-E416-48B3-AE96-C853DB349B64/TestApp.app/Frameworks/TestFramework.framework
2014-11-19 11:48:01.325 TestApp[95937:60b] ImagePath:/Users/nbkqkka/Library/Developer/CoreSimulator/Devices/A64CFDA9-EB0E-4B65-B119-A213CD500217/data/Applications/C942AA07-E416-48B3-AE96-C853DB349B64/TestApp.app/Frameworks/TestFramework.framework/Pic2.JPG
2014-11-19 11:48:01.474 TestApp[95937:60b] Image:(null)
The documentation for imageNamed says:
The name of the file. If this is the first time the image is being
loaded, the method looks for an image with the specified name in the
application’s main bundle.
It doesn't say anything about loading from a full path.
Can you use:
+ (UIImage *)imageWithContentsOfFile:(NSString *)path
instead?

Release memory used for UITableView.cell.image after leaving UIViewController

I have a UIViewController with UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate protocols. The UIViewController contains UITableView where I load some data from Core Data.
The loaded data include name, subtitle and an image.
They are set like:
cell.textLabel.text = [NSString stringWithFormat:#"%#", artist.title];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# year", artist.year];
NSString *fileName = [NSString stringWithFormat: #"%#/%#", [[NSBundle mainBundle] resourcePath], artist.imageSmall];
cell.imageView.image = [UIImage imageWithContentsOfFile:fileName];
As I figured out before, [UIImage imageNamed:] caches the image which causes memory leaks. That's why I applied imageWithContentsOfFile method in code, where I needed to load big-size images. And it worked great. But it doesn't seem to work fine within my UITableView. Or I do smth wrong of cause :)
Here my images are not so heavy, they're like 20-40kb per image. It's ok even if I load 50 images per UITableView. It takes about 5Mb of memory to show, for example, 50 artists' photos per category. But what I noticed is that when I leave my ViewController and load it again via another indexPath (I open some other category cell and going to view the artists from that category) the memory used by app continues to increase. If I browse through 20 categories, then I get 100Mb memory usage. It doesn't look like the ARC work fine here.
So, how can I release the memory or destroy UITableView after moving back from my UIViewController?
2 hours later I found solution %)
I figured out to declare UITableView as (weak, nonatomic) instead of (strong, nonatomic).
And in ViewDidDisappear method I call
[self.tableView removeFromSuperview];
and memory releases successfully.

XCode Build Parse Error 'Unexpected # in Program'

I'm following a tutorial for creating an animation using Xcode Version 4.5.2 in Mountain Lion 10.8.2. When trying to build the code below, I get a Parse Error Unexpected '#' in program showing up for the 'hopAnimation=' line. While searching, I have found examples that build simple animations in a different way, but nothing that seems to address this particular problem. I'm a noob to XCode programming and if anyone could help me correct the syntax, I would highly appreciate it. I would also like to thank all the contributors to stackflow for making this such a valuable resource. Searching for the answers to most of my prior questions always seemed to have you guys at the top of the results list.
ViewController.m
- (void)viewDidLoad
{
// load all the frames of our animation into an array
NSArray *hopAnimation;
hopAnimation=[[NSArray alloc] arrayWithObjects:
[UIImage imageNamed:#”frame-1.png”],
[UIImage imageNamed:#”frame-2.png”],
[UIImage imageNamed:#”frame-3.png”],
[UIImage imageNamed:#”frame-4.png”],
[UIImage imageNamed:#”frame-5.png”],
[UIImage imageNamed:#”frame-6.png”],
[UIImage imageNamed:#”frame-7.png”],
[UIImage imageNamed:#”frame-8.png”],
[UIImage imageNamed:#”frame-9.png”],
[UIImage imageNamed:#”frame-10.png”],
[UIImage imageNamed:#”frame-11.png”],
[UIImage imageNamed:#”frame-12.png”],
[UIImage imageNamed:#”frame-13.png”],
[UIImage imageNamed:#”frame-14.png”],
[UIImage imageNamed:#”frame-15.png”],
[UIImage imageNamed:#”frame-16.png”],
[UIImage imageNamed:#”frame-17.png”],
[UIImage imageNamed:#”frame-18.png”],
[UIImage imageNamed:#”frame-19.png”],
[UIImage imageNamed:#”frame-20.png”],nil];
self.bunnyView1.animationImages=hopAnimation;
self.bunnyView2.animationImages=hopAnimation;
self.bunnyView3.animationImages=hopAnimation;
self.bunnyView4.animationImages=hopAnimation;
self.bunnyView5.animationImages=hopAnimation;
self.bunnyView1.animationDuration=1;
self.bunnyView2.animationDuration=1;
self.bunnyView3.animationDuration=1;
self.bunnyView4.animationDuration=1;
self.bunnyView5.animationDuration=1;
[super viewDidLoad];
}
There is no init method called arrayWithObjects. There is initWithObjects, or simply [NSArray arrayWithObjects] (without alloc), but this will not work. Also, your quotes are the "smart quotes", the curly ones. I don't know if it's like that in Xcode, but you'll probably have to use straight quotes (") to make that work, too.

AVAudioPlayer is releasing before playing?

I'm making a soundboard app and I use this code to play mp3 files:
-(IBAction)playSound
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"mysound" ofType:#"mp3"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate=self;
[theAudio play];
[theAudio release];
}
When I include [theAudio release]; the sound doesn't play. If I take it out it plays but I don't want to have memory leaks. How can I fix this?
It would be very helpful if you could include whatever code I need to add. I'm new to programming (besides TrueBasic I've used in school) so I'm unfamiliar with Objective-C.
wait til the audio finishes via a delegate to release the audio. I believe there are a number of posts exactly like this on the site if you search, they will have the specific delegate code.
This is only because you use local variable. so theAudio will released immediately.
You should define it as class member and assignment it here. so when this function finished, it still work too.

NSImage → NSURL → Custom Object

My application is trying to create custom objects from NSImage objects (coming from the pasteboard) but my current process only takes in image URLs.
I'd like to avoid major changes at this point so I was wondering if there was any way to get the URL of an NSImage (it seems like a reasonable expectation since one can initialize an NSImage from a URL)
Thanks.
EDIT (answer)
I went a slightly different route. Instead of getting the content of the pasteboard as an array of NSImage, I simply got it as an array of NSURL. I can then feed those into my process.
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
NSArray *classArray = [NSArray arrayWithObject:[NSURL class]];
NSDictionary *options = [NSDictionary dictionary];
BOOL ok = [pasteboard canReadObjectForClasses:classArray options:options];
if (ok) {
NSArray *URLs = [pasteboard readObjectsForClasses:classArray options:options];
}
Quote by BlazingFrog:
(it seems like a reasonable expectation since one can initialize an NSImage from a URL)
Lets say I initialize a NSString by using:
NSString * theString = [NSString initWithContentsOfURL: encoding: error: ];
I'm sure it's not possible to retrieve the original NSURL from the NSString.
And I'm quite sure the same applies to NSImage. (Actually, completely sure.)
Indeed NSImage can be initialized by initWithContentsOfURL:.
But it can also be initialized by initWithData: or initWithPasteboard:.
The NSURL is no strict requirement for initializing a NSImage.
In other words, the NSImage might be initialized without using a URL.
The NSImage is simply a container for image representations.
Quote by Apple:
An NSImage object manages a group of image representations.
Solutions
Change you 'process' to accept NSImage.
Write the NSImage to a temporary file and use that file path.
If the image is being delivered via the standard pasteboard (i.e. the copy/paste mechanism) then there is no way to refer to it by URL because it might not have one. For instance, if you open a document in Word or Pages, select an image and copy it there is no possible way to create a URL reference to that image. It's on the pasteboard but not in the file system in a form you can access.
I think that you're going to have to modify your code to handle NSImage objects directly.

Resources