SoundCloud OSX Oauth process doesn't create account unless cancelled - macos

I've been trying to use the CocoaSoundCloudAPI to create a basic desktop app for OSX in Cocoa.
I'm struggling with authentication. Clicking a login button opens up an external browser window that tries to give my app authentication. If I click "Connect" the connect button shows a lovely animation... forever, and [SCSoundCloud account] is null.
However, if I click "Cancel" in the external browser window during this process, I see that SCAccount becomes !nil
Can anyone explain this?
Here's my code:
#import "SCMAppDelegate.h"
#implementation SCMAppDelegate
+ (void)initialize
{
[SCSoundCloud setClientID:#"MYID"
secret:#"MYSECRET"
redirectURL:[NSURL URLWithString:#"sampleproject1://oauth"]];
}
- (IBAction)login:(id)sender
{
[SCSoundCloud requestAccessWithPreparedAuthorizationURLHandler:^(NSURL *preparedURL){
// Load the URL in a web view or open it in an external browser
[[NSWorkspace sharedWorkspace] openURL:preparedURL];
}];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
{
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
andSelector:#selector(handleURLEvent:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
}
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
withReplyEvent:(NSAppleEventDescriptor*)replyEvent;
{
NSString* url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
BOOL handled = [SCSoundCloud handleRedirectURL:[NSURL URLWithString:url]];
if (!handled) {
NSLog(#"The URL (%#) could not be handled by the SoundCloud API. Maybe you want to do something with it.", url);
}
NSLog(#"This is the account: %#", [SCSoundCloud account]);
}
#end
I've been using https://github.com/soundcloud/CocoaSoundCloudAPI/blob/master/GeneralUsage.md as a guide, and have found most things to work. Can anyone push me in the right direction?

I did some NSLogging and found that, in fact, I was receiving a valid SoundCloud Account object, it just needed some more time to receive the object back.
I was, however, surprised that my external browser window never received a notification to indicate that connection had completed - is this an error on my behalf or a regular occurrence when it comes to external oauth2 requests?
It seems that, even if I use Facebook authorisation with my app, I never get notified in the browser page that authentication has completed. Does anyone know how I can achieve this? I'm quite sure that my callback url is correct, but I'll keep trying...

Related

iOS8 plugin pinterest.ShareExtension interrupted

I have an iOS app that uses UIActivityViewController for sharing. When I try to share via Pinterest I see the Pinterest share dialog very briefly and then it disappears.
The following message is printed to the log:
plugin pinterest.ShareExtension interrupted
What is causing this error? What do I need to do to make Pinterest sharing work?
I already had a UIActivityItemSource to generate my share link. I was able to resolve this issue by returning an NSString rather than NSURL to the Pinterest extension.
if ([activityType isEqualToString:PinterestExtentionType]) {
//Unclear why but passing an NSURL to the Pinterest iOS8 extention results in it instantly closing
return shareUrlString;
} else {
return [NSURL URLWithString:shareUrlString];
}

How to prevent setting of [NSApp dockTile] badgeLabel value that is set not by my code?

I have a push notifications with badge, sounds and alerts enabled.
If the program is not running - everything is fine. But when the program is running - I need to block all sounds, alerts and badges that are not generated by program, because I have a live connection to my server and receiving all events before APNS sends notifications to my mac device.
I've found the way to hide alerts, but I couldn't find any way to take over control on dockTile's icon badge.
if i do this:
-(void)application:(NSApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[[NSApp dockTile] setBadgeLabel:nil];
}
nothing is happened, the badge that is set by APNS still persists. I tried to KVO on badgeLabel or dockTileNumber property as shown here, but observeValueForKeyPath:ofObject:change:context: is never called. How do APNS sets the badgeLabel? Maybe I am doing something wrong and there is a correct way to disable alerts/sounds/badges when the program is running?
Since i did not found any solutions to do it correctly, i will accept my workaround:
-(void)application:(NSApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[application dockTile].badgeLabel = #" ";
[application dockTile].badgeLabel = #"";
}
Alerts may be disabled via NSUserNotificationCenterDelegate delegate method userNotificationCenter:shouldPresentNotification::
-(BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
{
//apple push notification alert will contain userInfo with aps payload, so disable here
if (notification.userInfo[#"aps"])
return NO;
return YES;
}
I haven't found any ways to disable sounds.

Catch registered URL scheme and launch app

I managed to launch my application whenever a URL scheme is called via the browser, by putting this scheme in the info.plist and adding these 2 lines:
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
[appleEventManager setEventHandler:self andSelector:#selector(getUrl:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
and correctly implementing my getUrl function.
So I tried putting the two lines above in my appDelegates's applicationWillFinishLaunching, applicationDidFinishLaunching and init. But in the three cases, I have the same scenario: if my app is already running, then the getUrl function is correctly called, by if the app is not launched, then getUrl is never called.
I found on other posts (How to handle with a default URL scheme and get url event on app open in objective c (Mac OSX)) but the suggestion which comes often is using the applicationWillFinishLaunching, which didn't work in my case.
Edit: here is my info.plist: http://pastebin.com/yM8zabvY
I'm not sure where things are going sour for you. I've set up a test project, in which I just pasted the CFBundleURLTypes key from your Info.plist, and I used this in my app delegate:
-(void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor*)reply
{
NSLog(#"%#", event);
}
-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
// Register ourselves as a URL handler for this URL
[[NSAppleEventManager sharedAppleEventManager]
setEventHandler:self
andSelector:#selector(getUrl:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
}
And it works just like I'd expect. I get the log message regardless of whether the app was already running or not when I run open "feed://test" in the terminal.
Have you verified that your app is the default handler for the feed: scheme?
You can inspect the system's URL schemes using RCDefaultApp or the Launch Services API (LSCopyDefaultHandlerForURLScheme).

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

WebView loads slowly in Mac OS

I have created plugin for Mail.app on Mac OS.
I'm using WebView to display web pages, all would be fine but web pages load slowly.
Then I created test cocoa application to compare loading time.
I was surprised when the test application loads page ~5 times faster.
In developer bar I saw my test application receives 304 code that indicates "the resource for the requested URL has not changed and cached resource can be used".
In contrast to the test application the plugin always receives 200 http code and loads resource again.
Maybe I should specify to use a cache in the webview, or I have some bundle permissions problems.
In the plugin, I tried to specify SharedURLCache like this
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:1024*1024*20
diskCapacity:1024*1024*5
diskPath:NSHomeDirectory()];
[NSURLCache setSharedURLCache:cache];
Then I tried subscribe to the ResourceLoadDelegate on the WebView and change request object like this
- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
{
if ([request cachePolicy] != NSURLRequestReturnCacheDataElseLoad)
{
return [NSURLRequest requestWithURL:[request URL]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:[request timeoutInterval]];
} else {
return request;
}
}
Also I tried to change properties on WebView
[[webView preferences] setUsesPageCache:YES];
[[webView preferences] setCacheModel:WebCacheModelPrimaryWebBrowser];
but it's all not working.
Thanks for help.

Resources