how to make NSURL point to local dir? - cocoa

reading Adium code today, found an interesting usage of NSURL:
NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:#"adium://%#/adium", [messageStyle.bundle bundleIdentifier]]];
[[webView mainFrame] loadHTMLString:[messageStyle baseTemplateForChat:chat] baseURL:baseURL];
I tried to log the url and got this adium://im.adium.Smooth Operator.style/adium, Then I created a blank project to see how to create such an NSURL but failed. When I sending loadHTMLString message to a webview's frame in my project, if the baseURL is nil, everything is fine, if not, I got a blank page in the view.
here is my code, the project name is webkit
NSURL *baseURL = [NSURL URLWithString:#"webkit://resource"];
//if baseURL is nil or [[NSBundle mainBundle] bundleURL], everything is fine
[[webView mainFrame] loadHTMLString:#"<html><head></head><body><div>helloworld</div></body></html>"
baseURL: baseURL];
[frameView setDocumentView:webView];
[[frameView documentView] setFrame:[frameView visibleRect]];
the question is how to make a self defined protocol instead of http://?

adium://%#/adium , first section is called protocol you can also register your protocol webkit: Take a look at How to map a custom protocol to an application on the Mac? and Launch Scripts from Webpage Links

[NSURLProtocol registerClass:[AIAdiumURLProtocol class]];
[ESWebView registerURLSchemeAsLocal:#"adium"];
I tried to find where did adium define the adium schema in the info.plist, unfortunately, there's nothing there, only some irc/xmpp protocols.
so I finally launched the debugger, and found the code above in the AIWebKitDelegate init method, anyway this is another way to register a self defined protocol~

Related

NSWorkspace throws error when launch the mail application

I tried the below code, it is working fine for me. Also am able to launch the mail application as well.
//Note the below path is coming from bundle identifier of Mail APP
NSString *path=#"/Applications/Mail.app"
NSURL *mailURL = [NSURL URLWithString:path];
NSError *err=nil;
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:mailURL
options:NSWorkspaceLaunchDefault
configuration: someData
error:&err];
But it throws me the below error message on console, What it means actually. How to resolve the below issue.
CFURLCopyResourcePropertyForKey failed because it was passed this URL which has no scheme: /Applications/Mail.app
The error is thrown because you are not creating a valid URL. The URL needs a scheme, in your case it is file: so the correct URL is file:///Applications/Mail. You need to create a file URL which works as follows:
NSString *path=#"/Applications/Mail.app";
NSURL *mailURL = [NSURL fileURLWithPath:path];
Note that your code breaks if the user ha moved Mail.app to another location. Also note that if the user doesn't use Apple's Mail app, it won't work well for the user either.
One possibility of doing it a more correct way is given here: How to launch New Message window in Mail.app from my application
Another option is to get the URL for Mail.app in a more fleixble way covering for users that have moved Mail.app. The idea is to use the bundle identifier and then ask NSWorkspace to launch this application by using
- (BOOL)launchAppWithBundleIdentifier:(NSString *)bundleIdentifier
options:(NSWorkspaceLaunchOptions)options
additionalEventParamDescriptor:(NSAppleEventDescriptor *)descriptor
launchIdentifier:(NSNumber **)identifier
(see also in detail here http://theocacao.com/document.page/183).

Has there been a change to the way Mac OSX Mavericks handles CFBundleURLName "Custom url" launches for applications?

I created an app which is launched from a custom url in any OSX browser. This worked just fine by adding a standard CFBundleURLName entry to the app's plist.
My application works by reading by parsing some of the parameters on the custom url and then reacting to them.
So for example with a custom url of:
foobar://param1/param2/param3
When clicking on the above url in a browser, OSX would launch my app and pass the actual custom url itself as the first argument to the app. Therefore in the app I could read the first arg and get the url the opened the app, and parse it for params I need.
This works fine in OSX 10.5-10.8, but in 10.9 Mavericks it appears to work slightly differently. Namely that if the application is not already running, it still launches the app but does not pass the custom url as first argument - so the app thinks it's just been launched manually by the user (such as selecting it from launchpad) rather than directly from a browser.
Weirdly, if the application is already open, then clicking the custom url DOES send the url string over to the app as first argument and functionality within the app occurs as expected.
I've tested this across 10.6->10.9 with new and old versions of my app and all exhibit the same behaviour. All work fine on first launch with versions before 10.9 Mavericks, but in 10.9 they don't get the url passed as first arg but then work on 2nd click once already running.
If anyone could shed some light on this I would be very grateful.
Where do you set up your URL handler? It needs to happen early. If you currently have it in applicationDidFinishLaunching, try to move it to applicationWillFinishLaunching.
The following works for me and logs the URL at launch even when the app is not running before I open the URL in Safari, for example. When I change WillFinishLaunching to DidFinishLaunching, I see exactly the behavior you describe.
#implementation AppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
[appleEventManager setEventHandler:self andSelector:#selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
NSAppleEventDescriptor *obj = [event descriptorForKeyword:keyDirectObject];
DescType type = [obj descriptorType];
if (type == typeChar) {
NSData *data = [obj data];
if (data) {
NSString *urlString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(#"url: %#", url);
}
}
}
#end

NSWorkspace launchApplication:showIcon:autolaunch: - how to check autolaunch flag?

I have implemented a login item as I was recommended in this post. In the helper app I launch the main app using NSWorkspace method launchApplication:showIcon:autolaunch:, sending YES to autolaunch parameter.
The problem is in following: I need to check if the applications was autolaunched not to show start tooltip. The only variant I found is [[NSUserDefaults standardUserDefaults] boolForKey:#"autolaunch"], and it returns NO always.
The problem could be solved using launch arguments - but sandbox, unfortunately, cuts them too.
Is there something I missed?
I use the following code to hide the launched application:
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:appPath] options:NSWorkspaceLaunchAndHide configuration:nil error:nil];
If you want to set additional parameters, you can give the method a custom configuration dictionary.
If you have the launcher inside the application bundle:
NSString *appPath=[[[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByAppendingPathComponent:#"MacOS/myApp"];

Prevent IOS WebView from caching images

Situation:
A native IOS5 App downloads a website from FTP to local storage and a webview displays the downloaded page. If there is a new version on the FTP-Server, the App will automaticly download the new version and override the old one in the local storage. Now the webview should load the new version.
Problem:
When the new version overwrides the old version, the name of some images will be the same. Now the webview will load every image from cache insteat from filesystem. -.-
Question:
Is there a possibility to prevent the webview loading all images from cache or clear the whole cache? What I cant do is changing the html or js of the downloaded page. So the approache to add a timestamp behinde every image (test.img?timestamp=23444) cant be done. The change has to be done in the IOS App.
What ive tryed already but failed:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
NSURL *url = [NSURL fileURLWithPath:[ftpPath stringByAppendingPathComponent:#"index.html"]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:1.0];
[[NSURLCache sharedURLCache] removeCachedResponseForRequest: urlRequest];
[webView stopLoading];
[webView loadRequest:urlRequest];
[webView reload];
webView.delegate = self;
Thank you so much for any help, i dont get it.
Cya Nando

Downloading an mp3 from link inside app

i'm making an mac app that downloads an mp3 from a link.
For example, this link: http://media.soundcloud.com/stream/VGGUdzU69Ng5?stream_token=2U9W2
As you can see, it is an mp3 file.
How can i download it to a specific path?
Thank you
The simplest way is to use NSURLDownload:
NSURL* url = [NSURL URLWithString:#"http://media.soundcloud.com/stream/VGGUdzU69Ng5?stream_token=2U9W2"];
NSString* destinationPath = [NSHomeDirectory() stringByAppendingPathComponent:#"someFile.mp3"];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
NSURLDownload* download = [[NSURLDownload alloc] initWithRequest:request delegate:nil];
[download setDestination:destinationPath allowOverwrite:NO];
Ideally you'd set an object as the delegate so you can receive progress notifications and then release the NSURLDownload object when finished.
Probably the simplest way would be to set a policy delegate for your web view, and have that delegate respond to the question of what to do with that link by telling the listener to download.
Edit: Oh, missed the part about “to a specific path”. I've no idea on that; sorry. I hope someone else can fill in that aspect.

Resources