ExternalAccessory串口通信


ExternalAccessory 使用文檔

項目下載地址

  • 前言

    公司希望通過串口通信的方式實現蘋果手機與公司產品進行通信,通過Lighting接口,也就是蘋果的數據線。蘋果的API ExternalAccessory就是來解決這個問題的。

👇以下介紹一下ExternalAccessory的用法

簡介

ExternalAccessory通過三個類來實現通信

  1. EAAccessory 代表外部設備,包含了外部設備的信息;
  2. EAAccessoryManager 外部設備的管理者;
  3. EASession 當與一個外部設備建立通信渠道后,整個會話由這個類操作;
為項目添加ExternalAccessory通信機制的步驟
1. 引入類庫
  引入framework ExternalAccessory.framework
  在使用時添加 #import <ExternalAccessory/ExternalAccessory.h>
2. 在plist 文件中加入 UISupportedExternalAccessoryProtocols 字段,這是一個數組,將所有用到的協議字符串加入到這個數組中。這里的協議字符串是外設提前預制的,需要與硬件開發人員確認。蘋果系統已經幫我們管理了已經連接的設備,這里添加協議名稱的目的是告訴系統我的APP可以與包含這個協議的外設進行交互。
  <key>UISupportedExternalAccessoryProtocols</key>
	<array>
		<string></string>
	</array>
3. 獲取已經與手機連接的全部外部設備,監聽設備的鏈接以及斷開的狀態變化。
     _accessoryList = [[NSMutableArray alloc] initWithArray:[[EAAccessoryManager sharedAccessoryManager] connectedAccessories]];//這個數組中包含的是 EAAccessory
     
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessoryDidConnect:) name:EAAccessoryDidConnectNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessoryDidDisconnect:) name:EAAccessoryDidDisconnectNotification object:nil];
    //調用這個方法告訴系統,當設備鏈接狀態發生改變時給APP發送通知。
    [[EAAccessoryManager sharedAccessoryManager] registerForLocalNotifications];
4. 根據protocolString 篩選出EAAccessory 創建會話 EASession ,並且監聽收到信息以及可以發送信息的回調。
- (EASession *)openSessionForProtocol:(NSString *)protocolString
{
    NSArray *accessories = [[EAAccessoryManager sharedAccessoryManager]
                            connectedAccessories];
    EASession *session = nil;
    
    for (EAAccessory *obj in accessories)
    {
        if ([[obj protocolStrings] containsObject:protocolString])
        {
            _accessory = obj;
            _accessory.delegate = self;
            break;
        }
    }
    
    if (_accessory)
    {
        session = [[EASession alloc] initWithAccessory:_accessory
                                           forProtocol:protocolString];
        if (session)
        {
            [[session inputStream] setDelegate:self];
            [[session inputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop]
                                             forMode:NSDefaultRunLoopMode];
            [[session inputStream] open];
            [[session outputStream] setDelegate:self];
            [[session outputStream] scheduleInRunLoop:[NSRunLoop currentRunLoop]
                                              forMode:NSDefaultRunLoopMode];
            [[session outputStream] open];
        }
    }
    
    return session;
}

#pragma mark - NSStream Delegate

- (void)stream:(NSStream*)theStream handleEvent:(NSStreamEvent)streamEvent
{
    switch (streamEvent)
    {
        case NSStreamEventHasBytesAvailable:
        {// Process the incoming stream data.
            [self receiveData];
        }
            break;
            
        case NSStreamEventHasSpaceAvailable:
        {// Send the next queued command.
            [self writeData];
        }
            break;
            
        default:
            break;
    }
    
}
  
5. 接收配套設備的信息,以及向配套設備發送信息。
接收數據:
-(void)receiveData
{
    NSInteger maxLength = 128;
    uint8_t readBuffer [maxLength];
    //是否已經到結尾標識
    BOOL endOfStreamReached = NO;
    // NOTE: this tight loop will block until stream ends
    while (! endOfStreamReached)
    {
        NSInteger bytesRead = [_session.inputStream read: readBuffer maxLength:maxLength];
        if (bytesRead == 0)
        {//文件讀取到最后
            endOfStreamReached = YES;
        }
        else if (bytesRead == -1)
        {//文件讀取錯誤
            endOfStreamReached = YES;
        }
        else
        {
            NSString *readBufferString =[[NSString alloc] initWithBytesNoCopy:readBuffer length:bytesRead encoding: NSUTF8StringEncoding freeWhenDone: NO];
            NSLog(@"收到設備信息:%@",readBufferString);
            TTSLOG(@"收到設備信息");
        }
    }
}


發送數據: 發送數據沒有必要在狀態回調后再發送,也可以通過判斷hasSpaceAvailable的狀態來決定是否能夠發送。
-(void)writeData
{
    BOOL isAvailable = _session.outputStream.hasSpaceAvailable;
    if (isAvailable == YES) {
        NSData *data = [[NSData alloc]initWithBase64EncodedString:@"出發了老鐵" options:NSDataBase64DecodingIgnoreUnknownCharacters];
        [_session.outputStream write:[data bytes] maxLength:data.length];
    }
    
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM