iOS Bluetooth 4.0 프로토콜 소개
CoreBluetooth에는 두 가지 주요 부분, 즉 Central과 Peripheral이 있는데 하나는 클라이언트 서버와 유사하다.CBPeripheralManager는 주변 장치로서 서버입니다.CBCentral Manager는 중앙 장치로서 클라이언트입니다.사용 가능한 모든 iOS 장치는 주변(Peripheral) 또는 중앙(Central)이 될 수 있지만 주변과 중앙이 동시에 될 수는 없습니다.
일반적으로 휴대전화는 클라이언트이고 설비(예를 들어 팔찌)는 서버이다. 왜냐하면 휴대전화가 팔찌라는 서버를 연결하기 때문이다.주변(Peripheral)은 데이터를 생성하거나 저장하는 장치이고 중앙(Central)은 이 데이터를 사용하는 장치입니다.너는 주변이 방송 데이터의 설비라고 생각할 수 있다. 그는 외부 세계에 방송하여 그에게 데이터가 있다고 말할 뿐만 아니라 제공할 수 있는 서비스도 설명했다.다른 한편, 중앙은 부근에 서비스가 있는지 스캔하기 시작했다. 만약에 중앙이 원하는 서비스를 발견하면 중앙은 주변 연결을 요청하고 연결이 성공하면 두 장치 간에 전송 데이터를 교환하기 시작한다.중앙과 주변을 제외하고 우리는 그들 둘이 교환한 데이터 구조를 고려해야 한다.이러한 데이터는 서비스에서 구조화되고 각 서비스는 서로 다른 특징(Characteristics)으로 구성되며 특징은 하나의 단일 논리 값을 포함하는 속성 유형이다.
Peripheral 구현 단계
일단 굿즈를 만들도록 하겠습니다.
_peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil];
다음은 에이전트의peripheral Manager Did UpdateState 방법에 응답하여peripheral의 상태 등 정보를 얻을 수 있습니다.
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { switch (peripheral.state) { case CBPeripheralManagerStatePoweredOn: { [self setupService]; } break; default: { NSLog(@"Peripheral Manager did change state"); } break; } }
주변 장치의 블루투스가 가능하다는 것을 발견했을 때, 다른 중앙 장치에 방송해야 할 서비스와 특징을 준비해야 한다. 여기서는 setup 서비스 방법을 호출해서 실현할 수 있다.모든 서비스와 특징은 하나의 UUID(unique identifier)로 표시해야 한다. UUID는 16bit 또는 128bit의 값이다.중앙-주변 앱을 만들려면 128bit의 UUID를 만들어야 합니다.당신은 자신의 UUID가 이미 존재하는 다른 서비스와 충돌할 수 없다는 것을 확인해야 합니다.만약 당신이 자신의 장치를 만들려면 표준위원회가 필요로 하는 UUID를 실현해야 한다.만약 당신이 단지 중앙 - 주변 앱을 만들 뿐이라면, 나는 당신이 맥 OS X의 Terminal을 열 것을 건의합니다.app, uidgen 명령으로 128bit의 UUID를 생성합니다.이 명령을 두 번 사용해서 두 개의 UUID를 생성해야 한다. 하나는 서비스에 쓰는 것이고, 하나는 특징에 쓰는 것이다.그리고 중앙과 주변 앱에 그들을 추가해야 합니다.이제view controller가 실행되기 전에 다음 코드를 추가합니다.
static NSString * const kServiceUUID = @"1C85D7B7-17FA-4362-82CF-85DD0B76A9A5"; static NSString * const kCharacteristicUUID = @"7E887E40-95DE-40D6-9AA0-36EDE2BAE253";
다음은 setup Service 방법입니다.
- (void)setupService { CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID]; self.customCharacteristic = [[CBMutableCharacteristic alloc] initWithType:characteristicUUID properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable]; CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID]; self.customService = [[CBMutableService alloc] initWithType:serviceUUID primary:YES]; [self.customService setCharacteristics:@[self.customCharacteristic]]; [self.peripheralManager addService:self.customService]; }
CBPeripheral Manager의addService 방법이 호출되면 CBPeripheral Manager Delegate의 - (void)peripheral Manager: (CBPeripheral Manager *)peripheral didAdd Service: (CB Service *) service error: (NSError *) error 방법에 응답합니다.이럴 때 우리가 방금 만든 서비스를 방송할 수 있다.
- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error { if (error == nil) { [self.peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey : @"ICServer", CBAdvertisementDataServiceUUIDsKey : @[[CBUUID UUIDWithString:kServiceUUID]] }]; } }
물론 여기까지는peripheral Manager의 일을 마쳤고 중앙 설비는 당신의 서비스를 받아들일 수 있습니다.하지만 이것은 정지된 데이터입니다. 당신은 - (BOOL) update Value: (NS Data *)value for Characteristic: (CB Mutable Characteristic *)characteristic on Subscribed Centrals: (NS Array *)centrals 방법으로 중앙에 동적 데이터를 생성할 수 있는 곳을 호출할 수 있습니다.
- (void)sendToSubscribers:(NSData *)data { if (self.peripheral.state != CBPeripheralManagerStatePoweredOn) { LXCBLog(@"sendToSubscribers: peripheral not ready for sending state: %d", self.peripheral.state); return; } BOOL success = [self.peripheral updateValue:data forCharacteristic:self.characteristic onSubscribedCentrals:nil]; if (!success) { LXCBLog(@"Failed to send data, buffering data for retry once ready."); self.pendingData = data; return; } }
central은 characteristic의 값을 구독합니다. 값을 업데이트할 때peripheral은 updateValue: forCharacteristic: onSubscribedCentrals: (NSarray*) centrals를 호출하여 그룹 안의 centrals에 대응하는 characteristic의 값을 업데이트합니다. 업데이트된 후peripheral은 모든 central을 위해 다음 에이전트를 한 번 가십시오.
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic
peripheral이 읽거나 쓰는 요청을 받아들일 때 다음 두 가지 프록시 방법에 응답합니다
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request - (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests
그럼 이제peripheral이 만들어졌어요.
중앙 만들기
중앙을 만들고 주변을 연결합니다. 현재 우리는 주변을 하나 가지고 있습니다. 중앙을 만들 수 있습니다.중앙이 바로 주변에서 보낸 데이터를 처리하는 장치다.
self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
Central Manager가 초기화되면 이 앱을 실행하는 장치가 BLE를 지원하는지 확인하기 위해 상태를 검사해야 합니다.CBCentralManagerDelegate를 구현하는 에이전트 방법:
- (void)centralManagerDidUpdateState:(CBCentralManager *)central { switch (central.state) { case CBCentralManagerStatePoweredOn: { [self.manager scanForPeripheralsWithServices:@[ [CBUUID UUIDWithString:kServiceUUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @YES }]; } break; default: { NSLog(@"Central Manager did change state"); } break; } }
앱의 장치가 블루투스를 지원할 때 CBCentral Manager의 실례적인 - (void) scan For Peripherals With Services: (NSArray *) 서비스 UIDs 옵션: (NS Dictionary *) 옵션 방법을 호출하여 지정한 서비스의peripheral을 찾는 데 사용합니다.일단 주변을 찾다가 발견되면 중앙의 대리는 다음과 같은 회답을 받을 것이다.
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { NSString *UUID = [peripheral.identifier UUIDString]; NSString *UUID1 = CFBridgingRelease(CFUUIDCreateString(NULL, peripheral.UUID)); NSLog(@"---- ----%@%@", UUID,UUID1); [self.manager stopScan]; if (self.peripheral != peripheral) { self.peripheral = peripheral; NSLog(@"Connecting to peripheral %@", peripheral); [self.manager connectPeripheral:peripheral options:nil]; } }
이때 방송 데이터와 신호 질량(RSSI-Received Signal Strength Indicator)이 첨부된 주변이 발견되었다.이것은 매우 멋진 매개 변수로 신호의 질을 알게 되면 너는 그것으로 원근을 판단할 수 있다.모든 방송, 스캔된 응답 데이터는advertisementData에 저장되며, CBAdvertisementData를 통해 접근할 수 있습니다.이럴 때 이 주변 장치를 연결할 수 있는데,
[self.manager connectPeripheral:peripheral options:nil];
다음 에이전트 방법에 응답합니다.
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { NSLog(@"---- ----"); [self.peripheral setDelegate:self]; [self.peripheral discoverServices:@[ [CBUUID UUIDWithString:kServiceUUID]]]; }
주변 서비스에 접근하는 CBCentral Manager Delegate 에이전트는 CBPeripheral의 실례를 되돌려줍니다. 그 - (void) discover 서비스: (NSArray *) 서비스 UIDs 방법은 주변 서비스에 접근하는 것입니다. 이 방법은 CBPeripheral Delegate 방법에 응답합니다.
- (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverServices:(NSError *)error { NSLog(@"----didDiscoverServices----Error:%@",error); if (error) { NSLog(@"Error discovering service: %@", [error localizedDescription]); [self cleanup]; return; } for (CBService *service in aPeripheral.services) { NSLog(@"Service found with UUID: %@", service.UUID); if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) { [self.peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:kCharacteristicUUID],[CBUUID UUIDWithString:kWrriteCharacteristicUUID]] forService:service]; } } }
위의 방법에 error가 없으면discoverCharacteristics 방법을 호출하여 주변에 서비스가 열거한 특징을 찾으라고 요청할 수 있습니다. 다음 방법에 응답합니다.
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { if (error) { NSLog(@"Error discovering characteristic: %@", [error localizedDescription]); return; } if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) { for (CBCharacteristic *characteristic in service.characteristics) { NSLog(@"----didDiscoverCharacteristicsForService---%@",characteristic); if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) { [peripheral readValueForCharacteristic:characteristic]; [peripheral setNotifyValue:YES forCharacteristic:characteristic]; } if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kWrriteCharacteristicUUID]]) { writeCharacteristic = characteristic; } } } }
이 때peripheral은 두 가지 방법을 호출할 수 있습니다. [peripheral readValue ForCharacteristic:characteristic] 이것은 특징값을 읽고 응답합니다. - (void)peripheral: (CBPeripheral *)peripheral didUpdateValue ForCharacteristic: (CBCharacteristic *)characteristic error: (NSError *)error;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];응답합니다 - (void)peripheral: (CBPeripheral*)peripheral didUpdateNotificationStateForCharacteristic: (CBCharacteristic*)characteristic error: (NSError*)error;
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { if (error) { NSLog(@"Error changing notification state: %@", error.localizedDescription); } // Exits if it's not the transfer characteristic if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]] ) { // Notification has started if (characteristic.isNotifying) { NSLog(@"Notification began on %@", characteristic); [peripheral readValueForCharacteristic:characteristic]; } else { // Notification has stopped // so disconnect from the peripheral NSLog(@"Notification stopped on %@. Disconnecting", characteristic); [self.manager cancelPeripheralConnection:self.peripheral]; } } } - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { NSLog(@"----Value---%@",characteristic.value); if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) { if (writeCharacteristic) { Byte ACkValue[3] = {0}; ACkValue[0] = 0xe0; ACkValue[1] = 0x00; ACkValue[2] = ACkValue[0] + ACkValue[1]; NSData *data = [NSData dataWithBytes:&ACkValue length:sizeof(ACkValue)]; [self.peripheral writeValue:data forCharacteristic:writeCharacteristic type:CBCharacteristicWriteWithoutResponse]; } } }
위의 방법 중 - (void) writeValue: (NSData*) data forCharacteristic: (CBCharacteristic*) characteristic type: (CBCharacteristicWriteType) type은 주변 장치에 데이터를 쓰는 방법으로 다음 방법에 응답합니다
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { NSLog(@"---didWriteValueForCharacteristic-----"); if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kWrriteCharacteristicUUID]]) { NSLog(@"----value ----"); } }
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.