
#.CENTRAL (아이폰)
1.뷰컨트롤러.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <CoreBluetooth/CoreBluetooth.h> | |
#import <UIKit/UIKit.h> | |
@interface ViewController : UIViewController <CBCentralManagerDelegate, CBPeripheralDelegate> | |
@property (strong, nonatomic) CBCentralManager *centralManager; | |
@property (strong, nonatomic) CBPeripheral *discoveredPeripheral; | |
@property (strong, nonatomic) CBCharacteristic *characteristic; //특성정보 | |
@property (strong, nonatomic) NSMutableData *data; | |
@property (weak, nonatomic) IBOutlet UITextView *textView; | |
@property (strong , nonatomic) NSMutableString *str; | |
@end | |
2.뷰컨트롤러.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
#define NAME @"" //블루투스 이름 | |
#define SERVICE @"" //서비스 | |
#define CHARACTERISTIC @"" //특성 | |
#import "ViewController.h" | |
#import "PeripheralManager.h" | |
@interface ViewController () | |
@end | |
@implementation ViewController | |
//스캔 | |
- (IBAction)scanStart:(id)sender { | |
NSLog(@"scanStart - !"); | |
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; | |
_data = [[NSMutableData alloc] init]; | |
} | |
//메시지 보내기 | |
- (IBAction)sendMsg:(id)sender { | |
NSLog(@"메시지 보내기.."); | |
//######## 휴대폰에서 특정 값을 던지면 연결 하기!#### | |
NSString *signNum = @"0"; | |
NSData *data = [signNum dataUsingEncoding:NSUTF8StringEncoding]; | |
[_discoveredPeripheral writeValue:data forCharacteristic:_characteristic type:CBCharacteristicWriteWithResponse]; | |
} | |
//연결끊기 | |
- (IBAction)cancelAction:(id)sender { | |
NSLog(@"cancelAction - !"); | |
[self cleanup]; | |
} | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
NSLog(@"viewDidLoad - !"); | |
_str = [[NSMutableString alloc]initWithString:@""]; | |
} | |
- (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central { | |
// You should test all scenarios | |
if (central.state != CBManagerStatePoweredOn) { | |
return; | |
} | |
if (central.state == CBManagerStatePoweredOn) { | |
//[_centralManager scanForPeripheralsWithServices:nil options:nil]; | |
// Scan for devices | |
[_centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:SERVICE]] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }]; | |
NSLog(@"Scanning started"); | |
//[_str appendString:@"Scanning started\n"]; | |
[_textView setText:_str]; | |
} | |
} | |
//연결 - 시도 | |
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{ | |
if(peripheral.name.length > 0){ | |
NSLog(@"Discovered %@ at %@", peripheral.name, RSSI); | |
if (_discoveredPeripheral != peripheral) { | |
// Save a local copy of the peripheral, so CoreBluetooth doesn't get rid of it | |
_discoveredPeripheral = peripheral; | |
// And connect | |
NSLog(@"Connecting to peripheral %@", peripheral); | |
[_str appendFormat:@"Connecting to peripheral %@\n", peripheral]; | |
[_textView setText:_str]; | |
[_centralManager connectPeripheral:peripheral options:nil]; | |
} | |
} | |
} | |
//연결 완료 | |
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { | |
NSLog(@"Connected"); | |
[_centralManager stopScan]; | |
NSLog(@"Scanning stopped"); | |
[_data setLength:0]; | |
peripheral.delegate = self; | |
[peripheral discoverServices:@[[CBUUID UUIDWithString:SERVICE]]]; | |
} | |
//서비스 찾기 | |
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ | |
if (error) { | |
[self cleanup]; | |
return; | |
} | |
for (CBService *service in peripheral.services) { | |
[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:CHARACTERISTIC]] forService:service]; | |
} | |
// Discover other characteristics | |
} | |
//특성 구독 | |
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { | |
if (error) { | |
[self cleanup]; | |
return; | |
} | |
for (CBCharacteristic *characteristic in service.characteristics) { | |
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:CHARACTERISTIC]]) { | |
[peripheral setNotifyValue:YES forCharacteristic:characteristic]; | |
_characteristic = characteristic; | |
} | |
} | |
} | |
//기기가 보내는 데이터 수신 | |
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{ | |
if (error) { | |
NSLog(@"Error"); | |
return; | |
} | |
NSString *stringFromData = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]; | |
NSLog(@"stringFromData : %@",stringFromData); | |
if (characteristic.value != nil) { | |
//NSLog(@"characteristic.value : %@" ,characteristic.value); // - byte 단위 | |
NSLog(@"characteristic.value.description : %@" ,characteristic.value.description); // | |
NSString *peripheralSendSign = characteristic.value.description; | |
NSLog(@"peripheralSendSign : %@",peripheralSendSign); | |
if([peripheralSendSign containsString:@"2"]){ | |
//주변기기가 던저 주는 데이터 종료 시키기 - | |
[_discoveredPeripheral setNotifyValue:NO forCharacteristic:characteristic]; | |
[_centralManager cancelPeripheralConnection:peripheral]; | |
[_data appendData:characteristic.value]; | |
}else if([peripheralSendSign containsString:@"0"]){ | |
NSLog(@"연결"); | |
} | |
} | |
} | |
//CBCentral이 특성 변경에 대한 통지상태 체크 | |
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{ | |
if (![characteristic.UUID isEqual:[CBUUID UUIDWithString:CHARACTERISTIC]]) { | |
return; | |
} | |
if (characteristic.isNotifying) { | |
NSLog(@"Notification began on %@", characteristic); | |
} else { | |
// Notification has stopped | |
[_centralManager cancelPeripheralConnection:peripheral]; | |
} | |
} | |
-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{ | |
NSLog(@"didWriteValueForCharacteristic ? 언제 호출되지?"); | |
} | |
//didWriteValueForCharacteristic | |
// | |
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ | |
[_centralManager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:SERVICE]] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }]; | |
} | |
//연결 실패 | |
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ | |
NSLog(@"Failed to connect"); | |
[self cleanup]; | |
} | |
//제거 | |
- (void)cleanup { | |
// See if we are subscribed to a characteristic on the peripheral | |
if (_discoveredPeripheral.services != nil) { | |
for (CBService *service in _discoveredPeripheral.services) { | |
if (service.characteristics != nil) { | |
for (CBCharacteristic *characteristic in service.characteristics) { | |
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:CHARACTERISTIC]]) { | |
if (characteristic.isNotifying) { | |
[_discoveredPeripheral setNotifyValue:NO forCharacteristic:characteristic]; | |
return; | |
} | |
} | |
} | |
} | |
} | |
} | |
[_centralManager cancelPeripheralConnection:_discoveredPeripheral]; | |
[_centralManager stopScan]; | |
} | |
@end |
#.PERIPHERAL (블루투스 기기)
1.기기정보
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef LE_Transfer_TransferService_h | |
#define LE_Transfer_TransferService_h | |
//블루투스 기기의 서비스 아이디와 특성아디를 적어준다! | |
//#define TRANSFER_SERVICE_UUID @"181C" | |
#define TRANSFER_SERVICE_UUID @"xxxxxx-xxxx-xxxx-xxx-xxxxx" | |
#define TRANSFER_CHARACTERISTIC_UUID @"xxxxxx-xxxx-xxxx-xx-xxxxxx" | |
#define NOTIFY_MTU 20 | |
#endif |
2.뷰컨트롤러.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <CoreBluetooth/CoreBluetooth.h> | |
#import "TransferService.h" | |
#import <UIKit/UIKit.h> | |
@interface ViewController : UIViewController<CBPeripheralManagerDelegate> | |
@property (strong, nonatomic) CBPeripheralManager *peripheralManager; | |
@property (strong, nonatomic) CBMutableCharacteristic *transferCharacteristic; | |
@property (strong, nonatomic) CBMutableService *transferService; | |
@property (strong, nonatomic) NSData *dataToSend; | |
@property (nonatomic, readwrite) NSInteger sendDataIndex; | |
@end |
3.뷰컨트롤러.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ViewController.h" | |
@interface ViewController () <UITextViewDelegate> | |
@property (strong, nonatomic) IBOutlet UITextView *textView; | |
@end | |
@implementation ViewController | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
//_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate: self queue:nil options:@{ CBCentralManagerOptionRestoreIdentifierKey:@"peripheralManagerIdentifier" }]; | |
_peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil]; | |
} | |
#pragma mark - Peripheral Methods | |
// | |
// Delegate for CBPeripheralDelegate | |
// | |
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral | |
{ | |
// CBPeripheralManagerState... state other than CBPeripheralManagerStatePoweredOn | |
if (peripheral.state != CBPeripheralManagerStatePoweredOn) { | |
NSLog(@"%s: peripheralManager state is now: %li",__PRETTY_FUNCTION__,(long)peripheral.state); | |
} | |
// CBPeripheralManagerStatePoweredOn state... | |
else { | |
NSLog(@"%s: peripheralManager powered on.",__PRETTY_FUNCTION__); | |
// Start with the CBMutableCharacteristic | |
_transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID] | |
properties:CBCharacteristicPropertyNotify | CBCharacteristicPropertyRead | |
value:nil | |
permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable]; | |
// Then the service | |
_transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID] primary:YES]; | |
// Add the characteristic to the service | |
_transferService.characteristics = @[_transferCharacteristic]; | |
// And add it to the peripheral manager | |
[_peripheralManager addService:_transferService]; | |
// Start advertising using a timed thread... this won't work without a timer because you must have time to for | |
// the peripheral manager to add the service. | |
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ | |
[_peripheralManager stopAdvertising]; | |
[_peripheralManager startAdvertising:@{CBAdvertisementDataServiceUUIDsKey : @[_transferService.UUID] }]; | |
NSLog(@"%s: started advertising with ServiceUUID: %@ and CharacteristicUUID: %@",__PRETTY_FUNCTION__,_transferService.UUID,_transferCharacteristic.UUID); | |
}); | |
} | |
} | |
//메시지 보내기 버튼 | |
- (IBAction)sendMsgButton:(id)sender { | |
NSLog(@"메시지 보내기 버튼!"); | |
[self.peripheralManager updateValue:[@"1" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
} | |
// | |
// Delegate for CBPeripheralDelegate | |
// | |
// Start sending data once we've got a subscriber to the characteristic | |
// | |
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic | |
{ | |
NSLog(@"%s: central subscribed to characteristic: localkey: %@ dataserviceUUIDs: %@ datasolicitedserviceuuidskey: %@",__PRETTY_FUNCTION__,CBAdvertisementDataLocalNameKey,CBAdvertisementDataServiceUUIDsKey,CBAdvertisementDataSolicitedServiceUUIDsKey); | |
[BackgroundTimeRemainingUtility NSLog]; | |
// Get the data | |
//self.dataToSend = [@"Hello from a bluetooth peripheral. Hope you get this just fine!" dataUsingEncoding:NSUTF8StringEncoding]; | |
// self.dataToSend = [@"1" dataUsingEncoding:NSUTF8StringEncoding]; | |
// Reset the index | |
//self.sendDataIndex = 0; | |
// Start sending | |
//[self sendData]; | |
// for (int i = 0; i < 10; i++) { | |
// | |
// } | |
[self.peripheralManager updateValue:[@"1" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
// [self.peripheralManager updateValue:[@"1" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
} | |
-(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request{ | |
NSLog(@"didReceiveReadRequest"); | |
} | |
-(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests{ | |
NSLog(@"didReceiveWriteRequests"); | |
for (CBATTRequest *request in requests) { | |
if (@available(iOS 11.0, *)) { | |
if ([request.characteristic.UUID isEqual:[CBUUID UUIDWithString:CBUUIDL2CAPPSMCharacteristicString]]) { | |
//#ifdef DEBUG | |
NSString *dataString = [[NSString alloc] initWithData:request.value encoding:NSUTF8StringEncoding]; | |
NSLog(@"Received from manager - %@", dataString); | |
//#endif | |
// if (self.delegate && [self.delegate respondsToSelector:@selector(BLEServiceDidReceiveData:peripheral:service:)]) { | |
// [self.delegate BLEServiceDidReceiveData:request.value peripheral:nil service:self]; | |
// } | |
} | |
} else { | |
// Fallback on earlier versions | |
} | |
} | |
} | |
// | |
// Sends the next amount of data to the connected central | |
// | |
- (void)sendData | |
{ | |
// First up, check if we're meant to be sending an EOM | |
static BOOL sendingEOM = NO; | |
NSLog(@"%s:",__PRETTY_FUNCTION__); | |
[BackgroundTimeRemainingUtility NSLog]; | |
// Special case if we're done sending the message | |
if (sendingEOM) { | |
// send it | |
BOOL didSend = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
// Did it send? | |
if (didSend) { | |
// It did, so mark it as sent | |
sendingEOM = NO; | |
NSLog(@"%s: send EOM succeeded.",__PRETTY_FUNCTION__); | |
} | |
else { | |
NSLog(@"%s: send EOM failed.. will try again.",__PRETTY_FUNCTION__); | |
} | |
} | |
// We're not sending an EOM, so we're sending data | |
else { | |
// Is there any left to send? | |
if (self.sendDataIndex >= self.dataToSend.length) { | |
// No data left. Do nothing | |
return; | |
} | |
// There's data left, so send until the callback fails, or we're done. | |
BOOL didSend = YES; | |
while (didSend) { | |
// Make the next chunk | |
// Work out how big it should be | |
NSInteger amountToSend = self.dataToSend.length - self.sendDataIndex; | |
// Can't be longer than 20 bytes | |
if (amountToSend > NOTIFY_MTU) amountToSend = NOTIFY_MTU; | |
// Copy out the data we want | |
NSData *chunk = [NSData dataWithBytes:self.dataToSend.bytes+self.sendDataIndex length:amountToSend]; | |
// Send it | |
didSend = [self.peripheralManager updateValue:chunk forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
// If it didn't work, drop out and wait for the callback | |
if (!didSend) { | |
return; | |
} | |
NSString *stringFromData = [[NSString alloc] initWithData:chunk encoding:NSUTF8StringEncoding]; | |
NSLog(@"Sent: %@", stringFromData); | |
// It did send, so update our index | |
self.sendDataIndex += amountToSend; | |
// Was it the last one? | |
if (self.sendDataIndex >= self.dataToSend.length) { | |
// It was - send an EOM | |
// Set this so if the send fails, we'll send it next time | |
sendingEOM = YES; | |
// Send it | |
BOOL eomSent = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil]; | |
if (eomSent) { | |
// It sent, we're all done | |
sendingEOM = NO; | |
NSLog(@"Sent: EOM"); | |
} | |
return; | |
} | |
} | |
} | |
} | |
@end |
파일
Center.zip
0.12MB
peri.zip
0.20MB
'아이폰 개발 > ios 개념&튜토리얼' 카테고리의 다른 글
IOS NSURLSession으로 Get 요청 Post 요청 - 구현 (0) | 2020.12.03 |
---|---|
IOS NSURLSession으로 Get 요청 Post 요청하기 - 개념 (0) | 2020.12.02 |
코어 오디오 - AudioStreamBasicDescription 정보출력 (0) | 2020.08.12 |
코어 오디오 - 사운드 파일 생성 하기 (0) | 2020.08.12 |
IOS 샌드박스 접근 로직 (0) | 2020.08.11 |