免责声明 - 我没有这条电缆,所以我无法测试它,也许代码不起作用。但这只是盲目的演示我该怎么做。这是启用 ARC 的代码。
SerialPortCommunication.h
#import <Foundation/Foundation.h>
@interface SerialPortCommunication : NSObject
- (void)readBytes:(UInt32)numberOfBytes
success:(void(^)( NSData *data ))success
failure:(void(^)( NSData *dataReadSoFar, NSError *error ))failure;
@end
SerialPortCommunication.m
#import "SerialPortCommunication.h"
#import "RscMgr.h"
#define BUFFER_SIZE 128
@interface SerialPortCommunication() < RscMgrDelegate > {
RscMgr *_rscMgr; // Resource Manager
BOOL _portAvailable; // Can we use port?
NSMutableData *_data; // Buffer for data
UInt32 _totalBytesToRead; // Number of total bytes to read
// Success block to call
void(^ _successBlock )( NSData *data );
// Failure block to call
void(^ _failureBlock )( NSData *dataReadSoFar, NSError *error );
UInt8 *_buffer;
}
@end
@implementation SerialPortCommunication
#pragma mark - Lifecycle
- (void)dealloc {
free( _buffer );
}
- (id)init {
self = [super init];
if ( self ) {
_rscMgr = [[RscMgr alloc] init];
[_rscMgr setDelegate:self];
_buffer = malloc( BUFFER_SIZE * sizeof( UInt8 ) );
// DO SERIAL PORT CONFIGURATION HERE
}
return self;
}
#pragma mark - Public
- (void)readBytes:(UInt32)numberOfBytes
success:(void(^)( NSData *data ))success
failure:(void(^)( NSData *dataReadSoFar, NSError *error ))failure {
if ( ! _portAvailable ) {
if ( failure ) {
// Create some NSError that port is not available
failure( nil, nil );
return;
}
}
if ( _data ) {
if ( failure ) {
// Create some NSError that port is in use
failure( nil, nil );
return;
}
}
_failureBlock = failure;
_successBlock = success;
_totalBytesToRead = numberOfBytes;
_data = [NSMutableData data];
// Now we're waiting for delegate methods
}
#pragma mark - RscMgrDelegate
- (void)cableConnected:(NSString *)protocol {
// From now on you can use serial port
_portAvailable = YES;
[_rscMgr open];
}
- (void)cableDisconnected {
// From now on you can't user serial port
_portAvailable = NO;
// Ouch, we can't read, fire failure
if ( _failureBlock ) {
// Create NSError which describes cable disconnection
_failureBlock( _data, nil );
}
// Our task ends here
_successBlock = nil;
_failureBlock = nil;
_data = nil;
_totalBytesToRead = 0;
}
- (void)portStatusChanged {
// Check status if everything's alright and you can still user serial port
// Set _portAvailable accordingly
// Replace if ( NO ) with condition if port is still alright and we can read
if ( NO ) {
if ( _failureBlock ) {
// Create NSError which describes status change and we can't use serial port
_failureBlock( _data, nil );
}
// Our task ends here
_successBlock = nil;
_failureBlock = nil;
_data = nil;
_totalBytesToRead = 0;
_portAvailable = NO;
} else {
_portAvailable = YES;
}
}
- (void)readBytesAvailable:(UInt32)length {
if ( ! _data ) {
// Here no one's interested in received data
// So you can decide if you want to save them for later use or trash them
// We are going to trash them
[_rscMgr read:_buffer length:MIN( BUFFER_SIZE, length )];
return;
}
UInt32 bytesToRead;
// First of all, we can't read more than our buffer size
bytesToRead = MIN( BUFFER_SIZE, length );
// Also it's enough to read only what user requested
UInt32 remainingBytes = _totalBytesToRead - _data.length;
bytesToRead = MIN( bytesToRead, remainingBytes );
// Now read bytes
UInt32 bytesRead = [_rscMgr read:_buffer length:bytesToRead];
if ( bytesRead > 0 ) {
[_data appendBytes:_buffer length:bytesRead];
}
if ( _data.length == _totalBytesToRead ) {
if ( _successBlock ) {
_successBlock( _data );
}
_successBlock = nil;
_failureBlock = nil;
_data = nil;
_totalBytesToRead = 0;
}
}
@end
串口使用
这就是我将如何使用我的课程。
#import "SerialPortUser.h"
#import "SerialPortCommunication.h"
@interface SerialPortUser() {
SerialPortCommunication *_serial;
}
@end
@implementation SerialPortUser
- (id)init {
self = [super init];
if ( self ) {
_serial = [[SerialPortCommunication alloc] init];
}
return self;
}
- (void)getData {
[_serial readBytes:81
success:^(NSData *data) {
// Here you have NSData with 81 bytes for sure
}
failure:^(NSData *dataReadSoFar, NSError *error) {
// Here you have NSData with dataReadSoFar.length bytes only
// read so far, because an error happens
// And error is in NSError *error
}];
}
@end