tapAtPoint on UIWebView subclass - objective-c

I have subclassed UIWebView so that I can get touch events and also implemented this handy method. I'm curious, if this will work on an actual iOS device. I'm not at the office, so I don't know if does. It seems to work in the simulator.
- (void) tapAtPoint:(CGPoint)point
{
id /*UIWebBrowserView*/ webBrowserView = nil;
id webViewInternal = nil;
object_getInstanceVariable(self, "_internal", (void **)&webViewInternal);
object_getInstanceVariable(webViewInternal, "browserView", (void **)&webBrowserView);
if (webBrowserView) {
[webBrowserView tapInteractionWithLocation:point];
}
}
Has anyone tried something like this? I for sure find out in the morning, lol.

Please try this code, Here its working fine.
/* TapDetectingWindow.m */
#import "TapDetectingWindow.h"
#implementation TapDetectingWindow
#synthesize viewToObserve;
#synthesize controllerThatObserves;
- (id)initWithViewToObserver:(UIView *)view andDelegate:(id)delegate {
if(self == [super init]) {
self.viewToObserve = view;
self.controllerThatObserves = delegate;
}
return self;
}
- (void)dealloc {
[viewToObserve release];
[super dealloc];
}
- (void)forwardTap:(id)touch {
[controllerThatObserves userDidTapWebView:touch];
}
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
if (viewToObserve == nil || controllerThatObserves == nil)
return;
NSSet *touches = [event allTouches];
if (touches.count != 1)
return;
UITouch *touch = touches.anyObject;
if (touch.phase != UITouchPhaseEnded)
return;
if ([touch.view isDescendantOfView:viewToObserve] == NO)
return;
CGPoint tapPoint = [touch locationInView:viewToObserve];
NSLog(#"TapPoint = %f, %f", tapPoint.x, tapPoint.y);
NSArray *pointArray = [NSArray arrayWithObjects:[NSString stringWithFormat:#"%f", tapPoint.x],
[NSString stringWithFormat:#"%f", tapPoint.y], nil];
if (touch.tapCount == 1) {
[self performSelector:#selector(forwardTapwithObject:pointArray afterDelay:0.5];
}
else if (touch.tapCount > 1) {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(forwardTap  object:pointArray];
}
}
#end
/* WebViewController.h */
#interface WebViewController : UIViewController<TapDetectingWindowDelegate> {
IBOutlet UIWebView *mHtmlViewer;
TapDetectingWindow *mWindow;
}
/* WebViewController.m */
- (void)viewDidLoad {
[super viewDidLoad];
mWindow = (TapDetectingWindow *)[[UIApplication sharedApplication].windows objectAtIndex:0];
mWindow.viewToObserve = mHtmlViewer;
mWindow.controllerThatObserves = self;
}
- (void)userDidTapWebView:(id)tapPoint
{
NSLog(#"TapPoint = %f, %f", tapPoint.x, tapPoint.y);
}
Thanks, Let me know if you face any problems.

short answer: Yes, I tried something like this in the same way and it works on the real devices as well (tested with iOS 6).
ARC version of your method:
- (void) tapAtPoint:(CGPoint)point
{
Ivar internalWebViewIvar = class_getInstanceVariable([self class], "_internal");
id internalWebView = object_getIvar(self, internalWebViewIvar);
Ivar browserViewIvar = class_getInstanceVariable(object_getClass(internalWebView), "browserView");
id browserView = object_getIvar(internalWebView, browserViewIvar);
if (browserView) {
[browserView performSelector:#selector(tapInteractionWithLocation:) withObject:[NSValue valueWithCGPoint:point]];
}
}

Related

Getting memory warnings after starting a new Cocos2d-iPhone project in ARC. Beginner

Have recently been teaching myself objective-c in order to learn Cocos2d.
Started a new project to teach myself the basics with a classic falling gems tetris-like game. The first step I took was to enable the project for ARC using edit > refactor, and selecting the last 4 files in the template.
So far have been able to add a single gem with a dynamically colored sprite through subclassing CCSprite, and move it along the XCoordinates while having it fall from the top. The gems are given a gemPos location – eg 5,3 – in order for me to later implement the matching methods.
Am getting an EXC_BAD_ACCESS warning when a few of the blocks stack up on top of each other after testing out the project for a while. Am confused as to why this is happening if ARC is enabled.
My clumsy code is as follows (have left out .h files):
Default helloworld layer:
-(id) init
{
if( (self=[super init]) ) {
oldGems = [[NSMutableArray alloc]init];
[self setIsTouchEnabled:YES];
[self newGem];
[self scheduleUpdate];
}
return self;
}
- (void)registerWithTouchDispatcher
{
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
oldPos = touchLocation;
return TRUE;
}
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
[self updateXCoord:(CGPoint)touchLocation];
}
- (void)updateXCoord:(CGPoint)touchLocation
{
CGPoint distance = ccpSub(touchLocation, oldPos);
float xDistance = distance.x;
if (abs(xDistance) >= 36) {
if (touchLocation.x > oldPos.x) {
[_thisGem setPosition:ccp([_thisGem position].x + 36, [_thisGem position].y)];
[_thisGem setGemPos:ccp([_thisGem gemPos].x+1,[_thisGem gemPos].y)];
NSLog(#"The gem position is %#", NSStringFromCGPoint([_thisGem gemPos]));
oldPos = touchLocation;
} else {
[_thisGem setPosition:ccp([_thisGem position].x - 36, [_thisGem position].y)];
[_thisGem setGemPos:ccp([_thisGem gemPos].x-1,[_thisGem gemPos].y)];
NSLog(#"The gem position is %#", NSStringFromCGPoint([_thisGem gemPos]));
oldPos = touchLocation;
}
}
}
- (void)newGem
{
if (_thisGem) {
PCGem *oldGem = _thisGem;
NSLog(#"Old gem position at %#", NSStringFromCGPoint([oldGem gemPos]));
[oldGems addObject:oldGem];
}
_thisGem = [[PCGem alloc] initWithGemColor];
[_thisGem setPosition:ccp(160, 450)];
[self addChild:_thisGem];
[_thisGem setGemPos:ccp(4,10)];
NSLog(#"Gem added with %# color", [_thisGem gemColorName]);
}
- (void)update:(ccTime)dt
{
if ([_thisGem gemPos].y > 0) {
[self spaceBelowOccupied];
[_thisGem setPosition:ccp([_thisGem position].x, [_thisGem position].y-1)];
[_thisGem setGemPos:ccp([_thisGem gemPos].x, floor([_thisGem position].y / 36))];
} else {
[self newGem];
}
}
- (void)spaceBelowOccupied
{
for (PCGem *occupiedTile in oldGems) {
if (CGRectIntersectsRect(occupiedTile.boundingBox, _thisGem.boundingBox)) {
NSLog(#"Collision detected!");
[self newGem];
}
}
}
And my clumsy PCGem class:
- (id)initWithGemColor
{
if ((self = [super initWithFile:#"gemGS.png"])) {
NSArray *gemColorList = [NSArray arrayWithObjects:(NSString *)#"blue", (NSString *)#"red", (NSString *)#"green", nil];
NSInteger randColor = arc4random_uniform(3);
switch (randColor) {
case 0:
{
[self setGemColorName:[gemColorList objectAtIndex:0]];
ccColor3B gemColorRGB = {0,0,255};
[self setColor:gemColorRGB];
break;
}
case 1:
{
[self setGemColorName:[gemColorList objectAtIndex:1]];
ccColor3B gemColorRGB = {255,0,0};
[self setColor:gemColorRGB];
break;
}
case 2:
{
[self setGemColorName:[gemColorList objectAtIndex:2]];
ccColor3B gemColorRGB = {0,255,0};
[self setColor:gemColorRGB];
break;
}
}
}
return self;
}
Which leads me to another question, which I can't seem to find the answer to. In examples of ARC enabled Cocos2d projects, I've seen the node convenience method used, which of course is alloc]init]autorelease]. But I thought you can't use Autorelease with ARC and this would cause a crash? How does this work?
Any ideas to my woes? Would greatly appreciate clarification :)
Cheers,
Adrian
I think it might be caused by editing an array while enumerating through it. In your update function you call spaceBelowOccupied:
- (void)spaceBelowOccupied
{
for (PCGem *occupiedTile in oldGems) {
if (CGRectIntersectsRect(occupiedTile.boundingBox, _thisGem.boundingBox)) {
NSLog(#"Collision detected!");
[self newGem];
}
}
}
then if newGem gets called while in your for loop and this loop succeeds:
if (_thisGem) {
PCGem *oldGem = _thisGem;
NSLog(#"Old gem position at %#", NSStringFromCGPoint([oldGem gemPos]));
[oldGems addObject:oldGem];
}
then you are adding an object to an array while enumerating through it. So change your spaceBelowOccupied to this and see if it works:
- (void)spaceBelowOccupied
{
for (PCGem *occupiedTile in [oldGems copy]) {
if (CGRectIntersectsRect(occupiedTile.boundingBox, _thisGem.boundingBox)) {
NSLog(#"Collision detected!");
[self newGem];
}
}
}
that way you make a copy of oldGems to enumerate through that will get autoreleased once you are done going through it.

Trying to make SplashScene (Cocos2d) form the book of Pablo Ruiz, and it doesnt work

I add this scene to project and run it at ProjectRunDelegate
it fell when method cFadeAndShow starts
Can anybody tell me whats the problem?
im using xCode 3.2.6
and cocos2d 1.0.1
Or maybe someone already has working splash scene to show some company's logos on starts of game
Thanks
#import "SplashScene.h"
#implementation SplashScene
-(id) init {
if ( (self = [super init])) {
[self addChild:[SplashLayer node]];
}
return self;
}
-(void)dealloc{
[super dealloc];
}
#end
#implementation SplashLayer
-(id) init {
if ( (self = [super init])) {
self.isTouchEnabled = YES;
NSMutableArray * splashImages = [[NSMutableArray alloc] init];
for (int i =1; i<=2; i++) {
CCSprite *splashImage = [CCSprite spriteWithFile:[NSString stringWithFormat:#"splash%d.png",i]];
if (splashImage == nil) {
CCLOG(#"splashImage is nil");
}
[splashImage setPosition:ccp(240,160)];
[self addChild:splashImage];
if (i!=1)
[splashImage setOpacity:0];
[splashImages addObject:splashImage];
}
[self fadeAndShow:splashImages];
}
return self;
}
-(void) fadeAndShow:(NSMutableArray *) images{ // add the meehods
if ([images count]<=1) {
[images release];
[[CCDirector sharedDirector]replaceScene:[GameScene scene]];
}
else {
CCSprite *actual = (CCSprite *)[images objectAtIndex:0];
[images removeObjectAtIndex:0];
CCSprite * next = (CCSprite *)[images objectAtIndex:0];
[actual runAction:[CCSequence actions:[CCDelayTime actionWithDuration:2], [CCFadeOut actionWithDuration:1],
[CCCallFuncN actionWithTarget:self selector:#selector(remove:)],nil]];
[next runAction:[CCSequence actions:[CCDelayTime actionWithDuration:2], [CCFadeIn actionWithDuration:1],
[CCDelayTime actionWithDuration:2],
[CCCallFuncND actionWithTarget:self selector:#selector(cFadeAndShow:data:) data:images],nil]];
}
}
-(void) cFadeAndShow:(id)sender dara:(void*)data{
NSMutableArray * images = (NSMutableArray *) data;
[self fadeAndShow:images];
}
-(void)remove:(CCSprite *)s{
[s.parent removeChild:s cleanup:YES];
}
-(void)dealloc{
[super dealloc];
}
#end
Here's an answer:
[[CCDirector sharedDirector] replaceScene: [CCTransitionZoomFlipAngular
transitionWithDuration:2
scene:[GameScene node]
orientation:kOrientationLeftOver]];

Objective-c [Xcode] CCAnimation not working, cocos2d

i have two animations declared in the player class, and i want to run then from another class but i can't here's my code (If you can't read it here it's on pastebin: http://pastebin.com/iy0eFMWL):
player.h
#interface Player : CCSprite {
CCAnimate *animationOllie;
CCRepeatForever *repeatNormal;
}
player.m:
#implementation Player
-(id)initWithFile:(NSString *)filename
{
if (self = [super initWithFile:filename]) {
self.velocity = ccp(0.0, 0.0);
CCAnimation *ollie = [CCAnimation animation];
[ollie setDelayPerUnit:0.05f];
[ollie addSpriteFrameWithFilename:#"ollie1.png"];
[ollie addSpriteFrameWithFilename:#"ollie2.png"];
animationOllie = [CCAnimate actionWithAnimation:ollie];
CCAnimation *normal = [CCAnimation animation];
[normal setDelayPerUnit:0.05f];
[normal addSpriteFrameWithFilename:#"normal1.png"];
[normal addSpriteFrameWithFilename:#"normal2.png"];
CCAnimate *animationNormal = [CCAnimate actionWithAnimation:normal];
repeatNormal = [CCRepeatForever actionWithAction:animationNormal];
[self runAction:repeatNormal];
}
return self;
}
-(void)animateThePlayer {
[self stopAction:repeatNormal];
[self runAction:animationOllie];
}
And in the GameScene Class:
GameScene.h:
#interface GamePlayLayer : CCLayerColor {
float yVel;
}
GameScene.m:
#import "Player.h"
#interface GamePlayLayer()
{
Player *player;
}
#end
#implementation GamePlayLayer
-(id) init
{
if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {
player = [[Player alloc] initWithFile:#"normal1.png"];
[self addChild:player];
self.isTouchEnabled = YES;
player.position = ccp(85,70);
[self schedule:#selector(update:)];
}
return self;
}
-(void)update:(ccTime)dt {
if (player.position.y > 70) {
yVel -= 0.1;
}
else {
if (yVel != 5.5) {
yVel = 0;
player.position = ccp(player.position.x, 70);
}
}
player.position = ccp(player.position.x, player.position.y + yVel);
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
yVel = 5.5;
[player animateThePlayer];
}
And that's it, it builds fine, and everything works but when i click the layer it crashes and i get this message:
0x1df609b: movl 8(%edx), %edi Thread 1: EXC_BAD_ACCESS (code=2,
address=0xf
What can i do? Thanks in advance
The first thing - you try to use autoreleased object. animationOllie will be released after your init method.
The second mistake is that you cannot reuse actions. When you need to run action, you have to recreate it.

Play video in Mac OS X 10.7

What is the simplest way to play a video programmatically with Objective-C in Mac OS X 10.7 (Lion)? And if I want to support OS X 10.6 (Snow Leopard) too?
I noticed that iOS AV Foundation was introduced to OS X 10.7. Unfortunately the documentation seems to be written for iOS and I found it confusing.
Here's a NSView subclass that plays a video given a URL, using AV Foundation (thus Mac OS X 10.7 upwards only). Based on the AVSimplePlayer sample code.
Header:
#interface RMVideoView : NSView
#property (nonatomic, readonly, strong) AVPlayer* player;
#property (nonatomic, readonly, strong) AVPlayerLayer* playerLayer;
#property (nonatomic, retain) NSURL* videoURL;
- (void) play;
#end
Implementation:
static void *RMVideoViewPlayerLayerReadyForDisplay = &RMVideoViewPlayerLayerReadyForDisplay;
static void *RMVideoViewPlayerItemStatusContext = &RMVideoViewPlayerItemStatusContext;
#interface RMVideoView()
- (void)onError:(NSError*)error;
- (void)onReadyToPlay;
- (void)setUpPlaybackOfAsset:(AVAsset *)asset withKeys:(NSArray *)keys;
#end
#implementation RMVideoView
#synthesize player = _player;
#synthesize playerLayer = _playerLayer;
#synthesize videoURL = _videoURL;
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.wantsLayer = YES;
_player = [[AVPlayer alloc] init];
[self addObserver:self forKeyPath:#"player.currentItem.status" options:NSKeyValueObservingOptionNew context:RMVideoViewPlayerItemStatusContext];
}
return self;
}
- (void) dealloc {
[self.player pause];
[self removeObserver:self forKeyPath:#"player.currentItem.status"];
[self removeObserver:self forKeyPath:#"playerLayer.readyForDisplay"];
[_player release];
[_playerLayer release];
[_videoURL release];
[super dealloc];
}
- (void) setVideoURL:(NSURL *)videoURL {
_videoURL = videoURL;
[self.player pause];
[self.playerLayer removeFromSuperlayer];
AVURLAsset *asset = [AVAsset assetWithURL:self.videoURL];
NSArray *assetKeysToLoadAndTest = [NSArray arrayWithObjects:#"playable", #"hasProtectedContent", #"tracks", #"duration", nil];
[asset loadValuesAsynchronouslyForKeys:assetKeysToLoadAndTest completionHandler:^(void) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self setUpPlaybackOfAsset:asset withKeys:assetKeysToLoadAndTest];
});
}];
}
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == RMVideoViewPlayerItemStatusContext) {
AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status) {
case AVPlayerItemStatusUnknown:
break;
case AVPlayerItemStatusReadyToPlay:
[self onReadyToPlay];
break;
case AVPlayerItemStatusFailed:
[self onError:nil];
break;
}
} else if (context == RMVideoViewPlayerLayerReadyForDisplay) {
if ([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) {
self.playerLayer.hidden = NO;
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
#pragma mark - Private
- (void)onError:(NSError*)error {
// Notify delegate
}
- (void)onReadyToPlay {
// Notify delegate
}
- (void)setUpPlaybackOfAsset:(AVAsset *)asset withKeys:(NSArray *)keys {
for (NSString *key in keys) {
NSError *error = nil;
if ([asset statusOfValueForKey:key error:&error] == AVKeyValueStatusFailed) {
[self onError:error];
return;
}
}
if (!asset.isPlayable || asset.hasProtectedContent) {
[self onError:nil];
return;
}
if ([[asset tracksWithMediaType:AVMediaTypeVideo] count] != 0) { // Asset has video tracks
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.frame = self.layer.bounds;
self.playerLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
self.playerLayer.hidden = YES;
[self.layer addSublayer:self.playerLayer];
[self addObserver:self forKeyPath:#"playerLayer.readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:RMVideoViewPlayerLayerReadyForDisplay];
}
// Create a new AVPlayerItem and make it our player's current item.
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
[self.player replaceCurrentItemWithPlayerItem:playerItem];
}
#pragma mark - Public
- (void) play {
[self.player play];
}
#end
"Simplest" depends on exactly what you're trying to do. If you want more control (e.g., rendering the movie as an OpenGL texture) or less (e.g., a completely independent window that you can just pop up and ignore), there might be different answers.
But for most use cases, if you want 10.6+ support, the simplest way to show a movie is QTKit. See the article "Using QTKit for Media Playback" in the Xcode documentation for a good starting point.

Is it possible to open a link in Google chrome and Opera like safari in iOS from iOS Application

I need a clarification that Is it possible to open a URL in Google Chrome and Opera browsers like Safari in iOS from iOS Application.
Anyone's help will be deeply appreciated.
For Google Chrome you can look here for some example code from google showing how to load a URL in Chrome instead of Safari https://developers.google.com/chrome/mobile/docs/ios-links
Opera supports the "ohttp" scheme so a similar thing can be done for that too.
Here is a URLOpener class to use,
Usage,
NSString * url = #"http://www.apple.com";
NSString * userAgent = BROWSER_CHROME;
URLOpener * opener = [[URLOpener alloc] initWithURLString:url browser:userAgent];
[opener openURL];
URLOpener.h
#define BROWSER_CHROME #"chrome"
#define BROWSER_OPERA #"opera"
#interface URLOpener : NSObject
#property (nonatomic, retain) NSURL * url;
#property (nonatomic, retain) NSString * browser;
- (id) initWithURL:(NSURL *)u;
- (id) initWithBrowser:(NSString *)b;
- (id) initWithURL:(NSURL *)u browser:(NSString *)b;
- (id) initWithURLString:(NSString *)us browser:(NSString *)b;
- (BOOL)openURL;
#end
URLOpener.m
#import "URLOpener.h"
#implementation URLOpener
#synthesize url, browser;
- (id) initWithURL:(NSURL *)u
{
self = [super init];
if (self) {
self.url = u;
}
return self;
}
- (id) initWithBrowser:(NSString *)b
{
self = [super init];
if (self) {
self.browser = b;
}
return self;
}
- (id) initWithURL:(NSURL *)u browser:(NSString *)b
{
self = [super init];
if (self) {
self.url = u;
self.browser = b;
}
return self;
}
- (id) initWithURLString:(NSString *)us browser:(NSString *)b
{
NSURL * u = [NSURL URLWithString:us];
return [self initWithURL:u browser:b];
}
- (BOOL)openURL
{
if ([BROWSER_CHROME compare:self.browser options:NSCaseInsensitiveSearch] == NSOrderedSame) {
return [self openInChrome];
} else if ([BROWSER_OPERA compare:self.browser options:NSCaseInsensitiveSearch] == NSOrderedSame) {
return [self openInOperaMini];
}else if ([[UIApplication sharedApplication] canOpenURL:self.url] )
{
return [[UIApplication sharedApplication] openURL:self.url];
} else {
NSLog(#"Could not open url: %#", self.url);
return NO;
}
}
- (BOOL) openInChrome
{
// is chrome installed??
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"googlechrome://"]])
{
NSString *scheme = self.url.scheme;
// Replace the URL Scheme with the Chrome equivalent.
NSString * chromeScheme = nil;
if ([scheme compare:#"http" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
chromeScheme = #"googlechrome";
} else if ([scheme compare:#"https" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
chromeScheme = #"googlechromes";
}
if (chromeScheme) {
NSString *absoluteString = [self.url absoluteString];
NSRange rangeForScheme = [absoluteString rangeOfString:#":"];
NSString *urlNoScheme = [absoluteString substringFromIndex:rangeForScheme.location];
NSString *chromeURLString = [chromeScheme stringByAppendingString:urlNoScheme];
NSURL *chromeURL = [NSURL URLWithString:chromeURLString];
return [[UIApplication sharedApplication] openURL:chromeURL];
} else {
return [[UIApplication sharedApplication] openURL:self.url];
}
} else {
return [[UIApplication sharedApplication] openURL:self.url];
}
}
- (BOOL) openInOperaMini
{
// is opera mini installed??
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"ohttp://"]])
{
NSString *scheme = self.url.scheme;
// Replace the URL Scheme with the opera equivalent.
NSString * operaScheme = nil;
if ([scheme compare:#"http" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
operaScheme = #"ohttp";
} else if ([scheme compare:#"https" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
operaScheme = #"ohttps";
}
if (operaScheme) {
NSString *absoluteString = [self.url absoluteString];
NSRange rangeForScheme = [absoluteString rangeOfString:#":"];
NSString *urlNoScheme = [absoluteString substringFromIndex:rangeForScheme.location];
NSString *operaURLString = [operaScheme stringByAppendingString:urlNoScheme];
NSURL *operaURL = [NSURL URLWithString:operaURLString];
return [[UIApplication sharedApplication] openURL:operaURL];
} else {
return [[UIApplication sharedApplication] openURL:self.url];
}
} else {
return [[UIApplication sharedApplication] openURL:self.url];
}
}
- (void) dealloc {
[url release];
[browser release];
[super dealloc];
}
#end
Stumbled on this... #karim provided awesome code here. I ran into similar problem and eventually wrote Choosy - you can use it in your project to add support for many 3rd-party apps.