NSUrl from NSString?

Go To StackoverFlow.com

0

Having a really hard time getting an NSString into an NSURL

NSURL *url = [NSURL URLWithString:@"http://.../social.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    for(id entry in JSON)
    {
        strTwitter= [entry valueForKeyPath:@"str1"];
        strFacebook =[entry valueForKeyPath:@"str2"];
        CCLOG(@"twitter: %@", strTwitter);
    }
} failure:nil];

[operation start];

elsewhere...

[[UIApplication sharedApplication] openURL:[NSURL URLWithString: strTwitter]]; 

And then I crash on the NSURL line with EXC_BAD_ACCESS

In mainMenu.h:

@interface mainMenuLayer : CCLayer
{
    NSString *strTwitter;
}

CCLOG prints the URL fine - no spaces; has https, etc... ?

.h

#import "cocos2d.h"

#import "menuHome.h"
#import "menuMenu.h"
#import "AFJSONRequestOperation.h"


@interface mainMenuLayer : CCLayer
{
    CCSprite *Background;
    CCSprite *logoBackground;
    CCSprite *logoName;
    menuHome *theMenuHome1;
    menuMenu *theMenuMenu1;

    CGSize size;
    CCMenu *bottomMenu;
    CCMenu *bottomMenu2;
    CCMenuItemImage *menuHouse;
    CCMenuItemImage *menuMenu2;
    CCMenuItemImage *menuPictures;
    CCMenuItemImage *menuContact;
    CCMenuItemImage *menuMore;    
    CCMenuItemImage *menuTemp;  

    CCMenuItemImage *menuTwitter;
    CCMenuItemImage *menuFacebook;
    CCMenuItemImage *menuWebsite;
    CCMenuItemImage *menuAbout;
    CCMenuItemImage *menuBlank;

    NSString *strTwitter;
    NSString *strFacebook;

    NSInteger moreVisible;

}
// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;

-(void) funcHome;
-(void) funcMore;
-(void) funcMenu2;


+(mainMenuLayer*) sharedMenuScene;
@end

.m

#import "mainMenu.h"
#import "constants.h"

@interface mainMenuLayer ()
@property(nonatomic, strong) NSString *strTwitter;
@end

// HelloWorldLayer implementation
@implementation mainMenuLayer

@synthesize strTwitter;


static mainMenuLayer *sharedMenuScene;

+(mainMenuLayer*) sharedMenuScene {
    NSAssert(sharedMenuScene != nil, @"not yet initilized");
    return sharedMenuScene;
}

+(CCScene *) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    mainMenuLayer *layer = [mainMenuLayer node];

    // add layer as a child to scene
    [scene addChild: layer];

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
-(id) init
{
    // always call "super" init
    // Apple recommends to re-assign "self" with the "super" return value
    if( (self=[super init])) {


        sharedMenuScene = self;
        // create and initialize a Label
        self.isTouchEnabled = YES;

        [[CCDirector sharedDirector]enableRetinaDisplay:YES];


        // ask director the the window size
        size = [[CCDirector sharedDirector] winSize];
        moreVisible = 0;


        //theMenuHome1.position = ccp(0.0f, 0.0f);

        logoBackground = [CCSprite spriteWithFile:@"logo_bg_640x120.png"];    
        [self addChild:logoBackground z: depthLevelMenu];
        logoBackground.position = ccp( size.width / 2, size.height - 30);

        logoName = [CCSprite spriteWithFile:@"res_name.png"];    
        [self addChild:logoName z: depthLevelMenuLogo];
        logoName.position = ccp( size.width / 2, size.height - 30);

        Background = [CCSprite spriteWithFile:@"background.png"];    
        [self addChild:Background z: depthLevelBackground];
        Background.position = ccp( size.width / 2, size.height / 2);

        menuHouse = [[CCMenuItemImage itemFromNormalImage:@"home_128x100_unselect.png" selectedImage:@"home_128x100_select.png" target:self selector:@selector(funcHome:)]retain];

        menuHouse.position =  ccp( 32, 25 );

        menuContact = [[CCMenuItemImage itemFromNormalImage:@"contact_128x100_unselect.png" selectedImage:@"contact_128x100_select.png" target:self selector:@selector(funcHome:)]retain];

        menuContact.position =  ccp( 96, 25 );

        menuMenu2 = [[CCMenuItemImage itemFromNormalImage:@"menu_128x100_unselect.png" selectedImage:@"menu_128x100_select.png" target:self selector:@selector(funcHome:)]retain];

        menuMenu2.position =  ccp( 160, 25 );

        menuPictures = [[CCMenuItemImage itemFromNormalImage:@"photos_128x100_unselect.png" selectedImage:@"photos_128x100_select.png" target:self selector:@selector(funcHome:)]retain];

        menuPictures.position =  ccp( 224, 25 );

        menuMore = [[CCMenuItemImage itemFromNormalImage:@"more_128x100_unselect.png" selectedImage:@"more_128x100_select.png" target:self selector:@selector(funcMore:)]retain];

        menuMore.position =  ccp( 288, 25 );


        bottomMenu = [CCMenu menuWithItems: menuHouse, menuContact, menuMenu2, menuPictures, menuMore, nil];
        bottomMenu.position =  CGPointZero;

        [self addChild: bottomMenu z:depthLevelMenu];
        [menuHouse selected];

        [self getSettings];
    }
    return self;
}


-(void) getSettings
{
    NSURL *url = [NSURL URLWithString:@"http://.../social.php"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        for(id entry in JSON)
        {
            strTwitter= [entry valueForKeyPath:@"str1"];
            strFacebook =[entry valueForKeyPath:@"str2"];
            CCLOG(@"twitter: %@", strTwitter);
        }
    } failure:nil];

    [operation start];

}


-(void) funcMenu2: (id) sender
{
    CCLOG(@"funcMenu2 Called");
    [menuTwitter unselected];
    [menuFacebook unselected];
    [menuWebsite unselected];
    [menuAbout unselected];
    [menuBlank unselected];
    [menuMore unselected];


    if(sender == menuTwitter)
    {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString: strTwitter]]; 
        CCLOG(@"url: %@", strTwitter);

        CCLOG(@"Twitter Selected");
        [sender selected];

    }
}
2012-04-03 23:18
by lsiunsuex


3

How is strTwitter instantiated? Looks like it is being released prior to the

[[UIApplication sharedApplication] openURL:[NSURL URLWithString: strTwitter]];

Statement

Make a private property for strTwitter (put this inside your .m file:

@interface mainMenuLayer ()
    @property(nonatomic, strong) NSString *strTwitter;
@end

Then right below the @implementation mainMenuLayer:

@synthesize strTwitter;

One other note is that you should get in the habit of using proper case when defining classes: MainMenuLayer vs mainMenuLayer

2012-04-03 23:21
by LJ Wilson
added the .h fil - lsiunsuex 2012-04-03 23:23
Updated the answer, as long as the strTwitter NSString object will only be reference in this class, you will be fine. If you need to set that property from another class, you will want to put that @property declaration inside your .h file instead - LJ Wilson 2012-04-03 23:33
It's still crashing with an EXCBADACCESS. I put it in exactly as you told me to; even tried putting the property in the .h - - lsiunsuex 2012-04-03 23:45
Can you post the entire class (.h and .m) - LJ Wilson 2012-04-03 23:50
added .h and . - lsiunsuex 2012-04-04 00:13
Where does funcMenu2 get called from? Unless something else is happening, strTwitter will not exist - LJ Wilson 2012-04-04 11:16
funcMenu2 is called from menuitems on another menu - same file, just another row below the first row - lsiunsuex 2012-04-04 11:19
Make sure you aren't calling from a class method. If you are, you will need to make that strTwitter string public in scope (move the @property declaration from inside the private area to the .h file - LJ Wilson 2012-04-04 11:21
I did that also last night (putting the property in the .h) and was having the same problem. Did a clean for the hell of it, quit and restarted X-Code, unplugged and plugged in my iPhone 4s, nothing (was reaching...). It's being called the same way that getSettings is. I've set variables like this before which is why I don't understand why its not working. It's all in the same file. X-Code auto completes it so it knows its there. Odd. I'll try the suggestions tonight when I get home. Thank you guys - lsiunsuex 2012-04-04 11:38


1

change "strTwitter= [entry valueForKeyPath:@"str1"];" to

self.strTwitter= [entry valueForKeyPath:@"str1"];

this will make sure it gets retained by the auto-generated setter. The way you are assigning strTwitter sidesteps the setter and just assigns the non-retained object to it. I make a habit of calling "self.{property} = {some value}" when assigning.

2012-04-04 01:17
by spoofwear
This works both ways. Test it and see. The "right" way to do it is to under-bar the ivar and synth to that - LJ Wilson 2012-04-04 11:17