10-19-2010, 11:13 PM
#1 (permalink )
Registered Member
Join Date: Oct 2010
Posts: 20
Debug my GKSession App: $200 bounty
Howdy, thanks to several people on this board that have been very generous with their time, I've managed to make a pair of iPhone apps that almost function properly. One of them makes an iPhone act like a remote control for a number of iPads which will present a slide show as a synchronized series of PNG files named "File-0001.PNG" through whatever. I've got the apps kinda working, one for the remote control which has a Back and Next button and a thumbnail of the slide being presented, and a different app that runs on the iPads (about 10 of them; the limit appears to be 15).
The problem is that I never get a call to the statedidchange delegate on either side. I've made sure the protocol name is the same for both apps so they ought to see each other. I've tried several wifi networks and even tried bluetooth between two units (not using peer picker since that won't work over wifi and bluetooth will only do 3 to 5 units). I assume that I haven't set up the delegates properly but it's beyond my understanding of the system to figure out what's wrong. A secondary problem is I'm probably not doing memory retain/release exactly right though the apps don't crash and all the variables look good in the debugger.
Anyway, I'm out of time to get this working and therefore will offer a $200 bounty to whomever is first to help me get it right. If you are experienced and know GKSession it will probably take you less than an hour. If more than one person helps I'll offer appropriate bounties. Anyway, here's the code:
First, the iPad app called NexShow, which acts as a GKSession client, basically listening for filenames of PNG files which it throws up on the screen. It should automatically find and connect to the server.
Code:
//
// NexShowAppDelegate.h
// NexShow
#import <UIKit/UIKit.h>
#import "NexShowAppDelegate.h"
@class NexShowViewController;
@interface NexShowAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
NexShowViewController *viewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet NexShowViewController *viewController;
@end
Code:
//
// NexShowAppDelegate.m
// NexShow
#import "NexShowAppDelegate.h"
#import "NexShowViewController.h"
@implementation NexShowAppDelegate
@synthesize window;
@synthesize viewController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
[[UIApplication sharedApplication] setIdleTimerDisabled:YES];
viewController.initNexShow;
NSMutableString *dork;
dork = [NSMutableString stringWithCapacity: 20];
[dork setString:@"File-0001.PNG"];
[viewController setSlide:dork];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
Code:
//
// NexShowViewController.h
// NexShow
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
#import "NexShowAppDelegate.h"
@protocol NexShowViewControllerDelegate;
@interface NexShowViewController : UIViewController <GKSessionDelegate> {
NSMutableString *slideNumber;
IBOutlet UIImageView *imgView;
NSMutableString *showingSlide;
GKSession *mySession;
NSString *sessionID;
}
-(void)setSlide: (NSMutableString *) slideNumber;
-(void)initNexShow;
@property (nonatomic, retain) GKSession *mySession;
@property (nonatomic, copy) NSMutableString *slideNumber;
@property (nonatomic, retain) UIImageView *imgView;
@end
Code:
//
// NexShowViewController.m
// NexShow
#import "NexShowViewController.h"
@implementation NexShowViewController
@synthesize mySession;
@synthesize slideNumber;
@synthesize imgView;
-(void) initNexShow {
NSString *nexSession = @"NexStep";
mySession = [[GKSession alloc] initWithSessionID: nexSession displayName: nil sessionMode:GKSessionModeClient];
mySession.delegate = self;
mySession.available = YES;
NSLog(@"ok, we have now started looking for a server");
}
-(void) session: (GKSession *) session peer:(NSString *) peerID didChangeState: (GKPeerConnectionState) state {
NSLog(@"GKSession didChangeState to %@", state);
if (GKPeerStateAvailable == state) {
NSLog(@"GKPeerStateAvailable, peerID is %@ ", peerID);
[mySession connectToPeer: peerID withTimeout:800];
}
}
-(void) receiveData: (NSData *) data fromPeer: (NSString *) peerID inSession: (GKSession *) session context: (void *) context {
NSMutableString *string =[NSKeyedUnarchiver unarchiveObjectWithData: data];
[self setSlide: string];
NSLog(@"received some data %@", string);
}
-(void)setSlide: (NSMutableString *) sNumber {
imgView.image = [UIImage imageNamed:sNumber];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
@end
In a reply to this post, I will give you the code for NexClick, the app that is the remote controller running on an iPhone. Due to the 10K limit I can't post both apps together.
10-19-2010, 11:14 PM
#2 (permalink )
Registered Member
Join Date: Oct 2010
Posts: 20
and here's the other app
Next, the remote control app called NexClick, which acts as a GKSession server, sending the filename of a PNG file to the clients. It should always accept a new client.:
Code:
//
// NexClickAppDelegate.h
// NexClick
#import <UIKit/UIKit.h>
#import "NexClickAppDelegate.h"
@class NexClickViewController;
@interface NexClickAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
NexClickViewController *viewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet NexClickViewController *viewController;
@end
Code:
//
// NexClickAppDelegate.m
// NexClick
#import "NexClickAppDelegate.h"
#import "NexClickViewController.h"
@implementation NexClickAppDelegate
@synthesize window;
@synthesize viewController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window addSubview:viewController.view];
[window makeKeyAndVisible];
application.idleTimerDisabled = YES;
viewController.initNexClick;
NSMutableString *crapola;
crapola = [NSMutableString stringWithCapacity: 16];
[crapola setString:@"0001"];
viewController.slideNumber = crapola;
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
Code:
//
// NexClickViewController.h
// NexClick
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
@protocol NexClickViewControllerDelegate;
@interface NexClickViewController : UIViewController <GKSessionDelegate> {
NSMutableString *slideNumber;
UIButton *back;
UIButton *next;
UIButton *logo;
IBOutlet UIImageView *imgView;
IBOutlet UILabel *label;
GKSession *mySession;
NSString *sessionID;
}
- (void)initNexClick;
-(IBAction)doBack;
-(IBAction)doNext;
-(IBAction)doLogo;
@property (nonatomic, retain) UIButton *back;
@property (nonatomic, retain) UIButton *next;
@property (nonatomic, retain) UIButton *logo;
@property (nonatomic, retain) UIImageView *imgView;
@property (nonatomic, retain) UILabel *label;
@property (nonatomic, copy) NSMutableString *slideNumber;
@property (nonatomic, retain) GKSession *mySession;
@end
Code:
//
// NexClickViewController.m
// NexClick
#import "NexClickViewController.h"
@implementation NexClickViewController
@synthesize back;
@synthesize next;
@synthesize logo;
@synthesize label;
@synthesize slideNumber;
@synthesize imgView;
@synthesize mySession;
- (void) initNexClick {
NSString *nexSession = @"NexStep";
mySession = [[GKSession alloc] initWithSessionID: nexSession displayName: nil sessionMode: GKSessionModeServer];
mySession.delegate = self;
mySession.available = YES;
NSLog(@"have initialized nexSession and now available NexStep service");
}
- (void) session: (GKSession *) session didReceiveConnectionRequestFromPeer: (NSString *) peerID {
NSLog(@"about to accept connction from peer %@", peerID);
[session acceptConnectionFromPeer: peerID error: nil];
NSLog(@"have accepted connection from peer %@", peerID);
}
- (IBAction) doBack {
NSInteger temp = [self.slideNumber intValue];
if (1 != temp) {temp--;};
NSMutableString *bollox;
bollox = [NSMutableString stringWithFormat:@"%04d", temp];
[self setSlideNumber: bollox];
label.text = self.slideNumber;
NSMutableString *bollox2;
bollox2 = [NSMutableString stringWithString: bollox];
[bollox2 insertString:@"Slide-" atIndex:0];
[bollox2 appendString:@".PNG"];
NSLog(@"about to send some stuff");
if ([[mySession peersWithConnectionState:GKPeerStateConnected] count] > 0) {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: bollox2];
[mySession sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];
}
imgView.image = [UIImage imageNamed:bollox2];
}
- (IBAction) doNext {
NSInteger temp = [self.slideNumber intValue];
temp++;
NSMutableString *bollox;
bollox = [NSMutableString stringWithFormat:@"%04d", temp];
[self setSlideNumber: bollox];
label.text = self.slideNumber;
NSMutableString *bollox2;
bollox2 = [NSMutableString stringWithString: bollox];
[bollox2 insertString:@"Slide-" atIndex:0];
[bollox2 appendString:@".PNG"];
NSLog(@"about to send the next slide");
if ([[mySession peersWithConnectionState:GKPeerStateConnected] count] > 0) {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: bollox2];
[mySession sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];
}
imgView.image = [UIImage imageNamed:bollox2];
}
- (IBAction) doLogo {
NSString *nothingString = @"Slide-0001.PNG";
if ([[mySession peersWithConnectionState:GKPeerStateConnected] count] > 0) {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: nothingString];
[mySession sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];
}
}
- (void)broadcastSlide:(NSString *)brSlide {
}
- (void)viewDidLoad {
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
10-20-2010, 10:59 AM
#3 (permalink )
Registered Member
Join Date: Oct 2010
Posts: 20
Deal Still Available
Hey, this deal is still available. I still need help!
10-20-2010, 03:53 PM
#4 (permalink )
Registered Member
Join Date: Apr 2010
Posts: 155
Quote:
Originally Posted by
tacobell
Hey, this deal is still available. I still need help!
One thing that may be preventing it from working is your debug code
Code:
NSLog(@"GKSession didChangeState to %@", state);
should be
Code:
NSLog(@"GKSession didChangeState to %i", state);
The GKPeerConnectionState is an ENUM and not an NSObject.
10-21-2010, 12:30 AM
#5 (permalink )
Registered Member
Join Date: Oct 2010
Posts: 20
thanks but...
Quote:
Originally Posted by
barrettj
One thing that may be preventing it from working is your debug code
Code:
NSLog(@"GKSession didChangeState to %@", state);
should be
Code:
NSLog(@"GKSession didChangeState to %i", state);
The GKPeerConnectionState is an ENUM and not an NSObject.
Yep, that's correct and it made the nslog confused but the actual connection problem is the fact I don't set the display name to something.
I may yet need additional help but for now please consider the $200 offer to be closed.
Thread Tools
Display Modes
Linear Mode
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
» Advertisements
» Online Users: 375
16 members and 359 guests
Abidullah , AppRocketeer , baja_yu , Brandt , BSH , Droverson , Duncan C , givensur , Kryckter , MasterX , Meoz , Punkjumper , SLIC , stanny , Tomsky , wassupdoc
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,646
Threads: 94,111
Posts: 402,867
Top Poster: BrianSlick (7,990)
Welcome to our newest member, locombiano89