How to send large file as chunks via MCSession NSOutputStream - ios

I want to send large video file to connected peer in chunks via NSOutputStream
I am using below code.
NSError *error;
self.outputStream = [_appDelegate.mcManager.session startStreamWithName:#"Mystream" toPeer:[[_appDelegate.mcManager.session connectedPeers] objectAtIndex:0] error:&error];
At receiver side NSStream delegate not receiving entire send data.
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
switch(eventCode) {
case NSStreamEventEndEncountered:
break;
case NSStreamEventHasBytesAvailable:
if ([aStream isKindOfClass:[NSInputStream class]]) {
}
break;
case NSStreamEventErrorOccurred:
break;
case NSStreamEventHasSpaceAvailable:
break;
case NSStreamEventNone:
break;
case NSStreamEventOpenCompleted:
break;
}
}

Related

CBCentralManager state is Off, even-though the bluetooth is ON

I am trying to check whether the bluetooth is turned on/off with the following code. But it returns CBManagerStatePoweredOff even-though the bluetooth is already on. I checked it in iPhone6s and iOS version 11.2.5(15D60). If i restart bluetooth manually on the settings, It returns CBManagerStatePoweredOn.
- (void)detectBluetooth
{
if(!bluetoothManager)
{
// Put on main queue so we can call UIAlertView from delegate callbacks.
// NSDictionary *options = #{CBCentralManagerOptionShowPowerAlertKey: #NO};
// bluetoothManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:options];
bluetoothManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
[bluetoothManager scanForPeripheralsWithServices:nil options:nil];
}
[self centralManagerDidUpdateState:bluetoothManager]; // Show initial state
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
NSString *stateString = nil;
switch(central.state)
{
case CBManagerStateResetting:
stateString = #"The connection with the system service was momentarily lost, update imminent.";
break;
case CBManagerStateUnsupported:
stateString = #"The platform doesn't support Bluetooth Low Energy.";
break;
case CBManagerStateUnauthorized:
stateString = #"The app is not authorized to use Bluetooth Low Energy.";
break;
case CBManagerStatePoweredOff:
stateString = #"Bluetooth is currently powered off.";
break;
case CBManagerStatePoweredOn:
[self goToSearchDevices];
break;
default: stateString = #"State unknown, update imminent."; break;
}
}

WatchOS 4 App: CBCentralManager state is always in CBManagerStateUnsupported

I'm developing an app for Apple Watch Series 3, and it seems that the state of CBCentralManager is always CBManagerStateUnsupported.
I'm using the following code:
#import <CoreBluetooth/CoreBluetooth.h>
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
NSString *stateString = nil;
switch(central.state)
{
case CBManagerStateResetting:
stateString = #"The connection with the system service was momentarily lost, update imminent.";
break;
case CBManagerStateUnsupported:
stateString = #"The platform doesn't support Bluetooth Low Energy.";
break;
case CBManagerStateUnauthorized:
stateString = #"The app is not authorized to use Bluetooth Low Energy.";
break;
case CBManagerStatePoweredOff:
stateString = #"Bluetooth is currently powered off.";
break;
case CBManagerStatePoweredOn:
stateString = #"Bluetooth is currently powered on and available to use.";
[central scanForPeripheralsWithServices:nil options:
[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0]
forKey:CBCentralManagerOptionShowPowerAlertKey]];
break;
default:
stateString = #"State unknown, update imminent.";
break;
}
}
What am I doing wrong?

Writing to NSOutputStream cause high cpu usage

While instrumenting my app I found that CPU usage jumps to 90% when writing data to output stream. Specifically, when network speed is very high. When I profile it With Timer instrument, found that most of the cpu is used for NSStream delegate call. Please Help to optimize writing technic as to low down the cpu usage.
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
case NSStreamEventOpenCompleted: {
_isConnected = YES;
if([self.delegate respondsToSelector:#selector(isFTPConnectionFoundForUpload:)])
[self.delegate performSelector:#selector(isFTPConnectionFoundForUpload:) withObject:_isConnected?#"YES":#"NO"];
} break;
case NSStreamEventHasSpaceAvailable: {
bytesWritten = [self.producerStream write:&self.buffer[0] maxLength:512];
if (bytesWritten == -1) {
[self stopSendWithStatus:#"Network write error"];
}
} break;
case NSStreamEventErrorOccurred: {
NSLog(#"producer stream error %#", [aStream streamError]);
[self stopSendWithStatus:#"Stream open error"];
} break;
case NSStreamEventEndEncountered: {
} break;
default: {
} break;
}
}

NSStream delegate method stream:handleEvent: crashing application with EXC_BAD_ACCESS code=1

I am using NSInputStream to upload media file to server in following way.
uploadInputStream = [[NSInputStream alloc] initWithFileAtPath:videoFilePath];
uploadInputStream.delegate = self;
[uploadInputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[uploadInputStream open];
And in NSStream delegate method stream:handleEvent: i am fetching chunk of media file and uploading to server.
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(#"Strem opened");
break;
case NSStreamEventHasBytesAvailable: {
uint8_t buf[1024*1024];
unsigned int len = 0;
len = [(NSInputStream *)aStream read:buf maxLength:1024*1024];
if(len)
{
#autoreleasepool {
NSMutableData *fileData = [NSMutableData data];
[fileData appendBytes:(const void *)buf length:len];
[self uploadVideo:fileData];
}
}
break;
}
case NSStreamEventHasSpaceAvailable:
break;
case NSStreamEventEndEncountered: {
break;
}
case NSStreamEventErrorOccurred:
break;
case NSStreamEventNone:
break;
default:
break;
}
}
So far so good and everything works fine in simulator. The issue is if i test this same code in real device (iPad-mini for now), it always crashing the application with EXC_BAD_ACCESS code=1 at strating of the delegate method stream:handleEvent: .
Anyone has any idea about this? Any help will be appreciated.
Thanks,
Jay Stepin.

AVAssetExportSession SLOW

I am using AVAssetExportSession to export audio files. It is working, though in a speed that is practical for use. I am setting up my exporter, getting my AVAsset, and starting the export. Here is the code. Any suggestions or insight will help.
[exporter exportAsynchronouslyWithCompletionHandler:^{
NSLog(#"we are now exporting");
int exportStatus = exporter.status;
switch (exportStatus) {
case AVAssetExportSessionStatusFailed: {
// log error to text view
NSError *exportError = exporter.error;
NSLog (#"AVAssetExportSessionStatusFailed: %#", exportError);
break;
}
case AVAssetExportSessionStatusCompleted: {
NSLog (#"AVAssetExportSessionStatusCompleted");
// set up AVPlayer
NSData *data = [NSData dataWithContentsOfURL:exportURL];
break;
}
case AVAssetExportSessionStatusUnknown: { NSLog (#"AVAssetExportSessionStatusUnknown"); break;}
case AVAssetExportSessionStatusExporting: { NSLog (#"AVAssetExportSessionStatusExporting"); break;}
case AVAssetExportSessionStatusCancelled: { NSLog (#"AVAssetExportSessionStatusCancelled"); break;}
case AVAssetExportSessionStatusWaiting: { NSLog (#"AVAssetExportSessionStatusWaiting"); break;}
default: { NSLog (#"didn't get export status"); break;}
}
[exporter release];
[exportURL release];
}];
You're probably causing some kind of conversion - that will be slow (not that much faster than realtime). Make sure you're using the passthrough preset, AVAssetExportPresetPassthrough.

Resources