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
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;
}
}
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?
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;
}
}
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.
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.