objective c - How to reconnect when a NSStream loses connection? -
i building app monitors position of user, , sends via socket our server. on app startup app connects socket on our server, , able send data server.
but when user changes cell wifi, or so, connection drops. i'm trying figure out how reconnect (automatic), can't find out how. can me?
the code i'm using (locationrecorder.m):
// // locationrecorder.m // #import "locationrecorder.h" #import <cordova/cdv.h> #import <corelocation/corelocation.h> #import <foundation/foundation.h> @implementation locationrecorder @synthesize locationmanager; nsinputstream *inputstream; nsoutputstream *outputstream; - (void)startupdates { // runs once when app starts locationmanager = [[cllocationmanager alloc] init]; locationmanager.delegate = self; locationmanager.desiredaccuracy = kcllocationaccuracybestfornavigation; [locationmanager startupdatinglocation]; [locationmanager startupdatingheading]; // connect socket [self initnetworkcommunication]; // set timer every 5 seconds [nstimer scheduledtimerwithtimeinterval:5 target:self selector:@selector(timerinterval:) userinfo:nil repeats:yes]; } - (void)timerinterval:(nstimer *) timer { cllocation *location = [locationmanager location]; // process location data [self processlocationdata:location]; } - (void)processlocationdata:(cllocation *)location { // format data prepare sending server nsstring *response = [nsstring stringwithformat:stringformat, utctime, utcdate, lat, lng, alt, speed, heading, imei, numsat, battery, cellno]; //nslog(@"%@", @"tx"); nsdata *data = [[nsdata alloc] initwithdata:[response datausingencoding:nsasciistringencoding]]; // check connection if ([outputstream streamstatus] != nsstreamstatusopen) { nslog(@"%@", @"reconnecting..."); [outputstream open]; } [outputstream write:[data bytes] maxlength:[data length]]; } - (void)initnetworkcommunication { cfreadstreamref readstream; cfwritestreamref writestream; cfstreamcreatepairwithsockettohost(null, (cfstringref)@"***.***.***.***", 9000, &readstream, &writestream); outputstream = (nsoutputstream *)writestream; // don't initialize inputstream since don't need 1 (the server not (yet) talk back) [outputstream setdelegate:self]; [outputstream scheduleinrunloop:[nsrunloop currentrunloop] formode:nsdefaultrunloopmode]; [outputstream open]; } - (void)stream:(nsstream *)thestream handleevent:(nsstreamevent)streamevent { switch (streamevent) { case nsstreameventnone: // can not connect host, no event fired break; case nsstreameventopencompleted: // connected! nslog(@"%@", @"connected socket"); break; case nsstreameventerroroccurred: // connection problem nslog(@"%@", @"connection lost"); [thestream open]; //this not work :-( break; case nsstreameventendencountered: // connection closed [thestream close]; [thestream removefromrunloop:[nsrunloop currentrunloop] formode:nsdefaultrunloopmode]; [thestream release]; thestream = nil; break; default: // unknown or untracked event break; } } @end
credits martin r simple solution.
i added [outputstream close] nsstreameventerroroccurred, , before send data socket in processlocationdata added following code:
// check connection if ([outputstream streamstatus] != nsstreamstatusopen) { nslog(@"reconnecting...", nil); [self initnetworkcommunication]; }
Comments
Post a Comment