iOS iBeacon: How to get all of proximityUUID programmatically? - ios

I want to see all of proximityUUID of advertising packets programmatically. Some articles say that it is impossible on iOS but Android is possible. But I cannot believe it because I found the fantastic app "BLExplr" has the feature. I need to implement the function into my app. Does anyone knows how to do it or good examples? Any help will be appreciated.
(UPDATE 2014/1/17)
I believe #davidgyoung answer is right. Estimote beacon's proximityUUID is "B9407F30-F5F8-466E-AFF9-25556B57FE6D" but displayed my Estimote beacon's UUID on BLExplr app is another ID.

Unfortunately, you cannot to this on iOS. When you say that BLExplr and LightBlue can do this, you are confusing the Bluetooth service UUID with the iBeacon Proximity UUID. These are two very different things.
The Bluetooth service UUID is visible to iOS, but has nothing to do with an iBeacon's identifiers, and is useless for working with iBeacons. The service UUID is generated by iOS each time a bluetooth device is seen, and stays the same only for the duration of time the bluetooth device is in range. If you take a bluetooth device away and bring it back later, it will have a different service UUID.
An iBeacon's identifiers (ProximityUUID, Major, Minor) are embedded inside the body of the Bluetooth advertisement. The problem on iOS devices is that Apple's CoreBluetooth APIs disallow access to the raw advertisement body, so no third-party app is able to read these identifiers. Apple only allows access to these identifiers using the special iBeacon CoreLocation APIs, but these APIs require you to know the Proximity UUID up front.
Sorry, I know this is not the answer you want to hear! (I'm sorry about it, too!) For what it's worth, you can do this on Android, on OSX Mavericks and Linux.
See details here.

davidgyoung is partially wrong about not being able to get iBeacon info. You actually can get the proximity UUID on OS X, but not iOS.
In a CBPeripheral's advertisingData, there should be a key called kCBAdvDataManufacturerData; It is an NSData representing the iBeacon advertising information. This key is only available on OS X.
Check that the 2nd byte is equal to 0x02, the 1st two bytes are equal to 0x004c (76 in decimal), and the 4th byte (in decimal) + 4 equals the data's length (should be 25).
NSRanges (sorry for Mac syntax)
Proximity UUID: NSMakeRange(4, 16)
Major: NSMakeRange(20,2)
Minor: NSMakeRange(22,2)
To make sure you're doing it right, you can log the values as hex (use the format string %x) and make sure they match the description of the NSData from whence they came.

NSRange uuidRange = NSMakeRange(4, 16);
NSRange majorRange = NSMakeRange(20, 2);
NSRange minorRange = NSMakeRange(22, 2);
NSRange powerRange = NSMakeRange(24, 1);
Byte uuidBytes[16];
[data getBytes:&uuidBytes range:uuidRange];
NSUUID *uuid = [[NSUUID alloc] initWithUUIDBytes:uuidBytes];
int16_t majorBytes;
[data getBytes:&majorBytes range:majorRange];
int16_t majorBytesBig = (majorBytes >> 8) | (majorBytes << 8);
int16_t minorBytes;
[data getBytes:&minorBytes range:minorRange];
int16_t minorBytesBig = (minorBytes >> 8) | (minorBytes << 8);
int8_t powerByte;
[data getBytes:&powerByte range:powerRange];
return #{ #"uuid" : uuid,
#"major" : #(majorBytesBig),
#"minor" : #(minorBytesBig),
#"power" : #(powerByte)
};
but the uuid is the DeviceUUID, not the ProximityUUID

Related

Sending a program change with a program number (patch number)

I have two Roland midi devices that behave the same when I try to send a bank and program change. It always sets it to the first patch of the bank. It won't change the patch I choose in the bank. Pro Logic can, however, switch to different banks.
The following example cause the devices to change to the bank but the program (patch) on the device defaults to the first in that bank and not number 9.
var event = AKMIDIEvent(controllerChange: 0, value: 89, channel: 0)
midiOut.sendEvent(event)
event = AKMIDIEvent(controllerChange: 32, value: 64, channel: 0)
midiOut.sendEvent(event)
event = AKMIDIEvent(programChange: 9, channel: 0)
midiOut.sendEvent(event)
Anyone have experience with sending this MIDI messages?
I was going through the same issue and was about to go crazy. It turns out the Program Change values in various MIDI data specifications, from various vendors, are 1 based. Not 0. Or perhaps it is the AudioKit implementation that is wrong?
So, instead of a programChange value of 9 you should use a value of 8. Here is my code for changing the current instrument on channel 0 to the Bösendorfer grand piano on a Yamaha Clavinova keyboard, where the programChange value in the MIDI data specification is designated as 1.
midiOut.sendControllerMessage(0, value: 108) // MSB sound bank selection
midiOut.sendControllerMessage(32, value: 0) // LSB sound bank selection
midiOut.sendEvent(AKMIDIEvent(programChange: 0, channel: 0)) // Initiate program change based on MSB and LSB selections
While reading various documentation about how MIDI works I also saw some forum posts describing keyboards that expect the LSB bank selection before the MSB bank selection. That is however not my understanding of how MIDI should work, but worth a try if you still cannot make it work with your Roland keyboards.

Is there a way to know the color (white, black, rose gold, etc) of an iOS device in Swift? [duplicate]

Is there any way or hack to detect on what color (black / white) iPhone, iPad or iPod touch the iOS is installed?
I want to load corresponding UI skins in case of Black or White devices.
There's a private API to retrieve both the DeviceColor and the DeviceEnclosureColor.
UIDevice *device = [UIDevice currentDevice];
SEL selector = NSSelectorFromString(#"deviceInfoForKey:");
if (![device respondsToSelector:selector]) {
selector = NSSelectorFromString(#"_deviceInfoForKey:");
}
if ([device respondsToSelector:selector]) {
NSLog(#"DeviceColor: %# DeviceEnclosureColor: %#", [device performSelector:selector withObject:#"DeviceColor"], [device performSelector:selector withObject:#"DeviceEnclosureColor"]);
}
I've blogged about this and provide a sample app:
http://www.futuretap.com/blog/device-colors/
Warning: As mentioned, this is a private API. Don't use this in App Store builds.
The answer to the question is NO (as of now) and personally I don't think it's worth much, because what if the end-user uses a skin or an additional casing for his iPhone?
I'd suggest to initially ask the user "Hey, what's the color of your phone?" and then do accordingly.
Additionally, a research provided me with this information, I'm not sure if it's TRUE or if is going to help you.
The serial number is the key :)
If aabccdddeef is the serial number of the iPhone 4, ee represents the Color, (A4=black). I hope some of you here check this information with yours to see if this is true.
Just my 2 cents worth - if anyone is looking for the iPhone 5c colors, the colors below are picked from the apple website.
Hope it is of use to anyone:-)
iPhone 5c Colors:
Green
R 179
G 243
B 142
HEX #B3F38E
Blue
R 123
G 195
B 252
HEX #7BC3FC
Yellow
R 255
G 243
B 141
HEX #FFF38D
Red
R 252
G 132
B 142
HEX #FF848E
White
R 239
G 239
B 239
HEX #EFEFEF
According to information sprinkled around the web, the color of the device is encoded in the serial number. iFixit's blog indicates that the third- and second-to-last positions hold the information: xxxxxxxxCCx For an iPhone 4, A4 indicates black. No one seems to have the code for a white iPhone 4, which is strange. One forum posting indicates that it might be DZ. Everyone seems to be just parroting everyone else's information here.
Another site, mydigitallife.com, has an article listing the color codes for various older models. In some cases, the three positions have to be read together in order to determine the color. According to this site, all iPhone 3Gs models have 3N in the color code position; 3NP indicates "Black 16GB 3Gs", and 3NQ indicates "White 16GB 3Gs". The original (2G) iPhone also uses all three positions to indicate size (there were no color options).
There are already a number of questions here on SO that will help you to get the device's serial number.
For debugging purposes I compiled a more comprehensive list of of possible deviceInfoForKey: keys.
Interesting keys to note (for this question) are DeviceRGBColor DeviceEnclosureRGBColor. The values appear to be an integer that represent the RGB value in the form 0x00rrggbb.
Here, for reference, are all the keys I found:
ActiveWirelessTechnology
AirplaneMode
assistant
BasebandCertId
BasebandChipId
BasebandPostponementStatus
BasebandStatus
BatteryCurrentCapacity
BatteryIsCharging
BluetoothAddress
BoardId
BootNonce
BuildVersion
CertificateProductionStatus
CertificateSecurityMode
ChipID
CompassCalibrationDictionary
CPUArchitecture
DeviceClass
DeviceColor
DeviceEnclosureColor
DeviceEnclosureRGBColor
DeviceName
DeviceRGBColor
DeviceSupportsFaceTime
DeviceVariant
DeviceVariantGuess
DiagData
dictation
DiskUsage
EffectiveProductionStatus
EffectiveProductionStatusAp
EffectiveProductionStatusSEP
EffectiveSecurityMode
EffectiveSecurityModeAp
EffectiveSecurityModeSEP
FirmwarePreflightInfo
FirmwareVersion
FrontFacingCameraHFRCapability
HardwarePlatform
HasSEP
HWModelStr
Image4Supported
InternalBuild
InverseDeviceID
ipad
MixAndMatchPrevention
MLBSerialNumber
MobileSubscriberCountryCode
MobileSubscriberNetworkCode
ModelNumber
PartitionType
PasswordProtected
ProductName
ProductType
ProductVersion
ProximitySensorCalibrationDictionary
RearFacingCameraHFRCapability
RegionCode
RegionInfo
SDIOManufacturerTuple
SDIOProductInfo
SerialNumber
SIMTrayStatus
SoftwareBehavior
SoftwareBundleVersion
SupportedDeviceFamilies
SupportedKeyboards
telephony
UniqueChipID
UniqueDeviceID
UserAssignedDeviceName
wifi
WifiVendor
As others have noted, no, there is no official way of getting this information. Apple clearly knows (look in iTunes when you sync), so they could make it available. Might be worth raising a Radar.

iOS BLE no Glucose Measurement notifications

Context:
- iOS 7.1.2 on iPhone 5c
- A glucose measuring "peripheral" (BT LE)
- Device and peripheral have been paired (introducing a code)
- Peripheral has >= 1 records on/in it.
- The behavior described below was reproduced several times. With the peripheral only having one record, and as well having made two new ones. The results (characteristic.value's) read are always the same.
I'm trying to read (receive) records from the peripheral using an iOS device the following way:
Make the glucose peripheral try to send its records to my iOS device.
Discover and connect to relevant peripheral (Glucose Service 0x1808) on iOS device.
In peripheral:didDiscoverServices:error: discover characteristics, which are Glucose Measurement (0x2A18), Glucose Measurement Context (0x2A34), Glucose Feature (0x2A51) and Record Access Control Point (0x2A52)
In peripheral:didDiscoverCharacteristicsForService:error: iterate over all characteristics and read values for those characteristics (via [_peripheral readValueForCharacteristic:characteristic])
Call [_peripheral setNotifyValue:YES forCharacteristic:characteristic] (for all but the "Glucose Feature" characteristic). This is triggered via a button click, when "everything has been loaded".
Request number of records available (triggered by user) via "Record Access Control Point" like:
char buffer[3];
// Op Code: 0x04 report number of stored records
buffer[0] = 0x04;
// Operator: 0x01 All records
buffer[1] = 0x01;
// Operand: 0x00 n/a
buffer[2] = 0x00;
NSData *data = [NSData dataWithBytes:buffer length:3];
[_peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
Callback calls peripheral:didUpdateValueForCharacteristic:error: delegate method and the updated value is 06000405. I don't fully understand the related specification (see link below), so I'm not able to interpret the response my self but either 5 or 6 in the LSO (Least Significant Octet) would mean a "success" (or at least not an error).
Trigger the request of all stored records (triggered by user) like:
char buffer[3];
// Op Code: 0x01 report stored records
buffer[0] = 0x01;
// Operator: 0x01 All records, 0x06 last one
buffer[1] = 0x01; // Tried 0x06 as well with the same result
// Operand: 0x00 n/a
buffer[2] = 0x00;
NSData *data = [NSData dataWithBytes:buffer length:3];
[_peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
Call back calls peripheral:didUpdateValueForCharacteristic:error: with an updated value of 06000105. Changing the second octet from 0x01 to 0x06 gave the same response (value). Which as well I'm not able to understand/interpret.
Nothing more happens. Neither on Glucose Measurement nor on Glucose Measurement Context.
Note: On Android it seems that one must also set the Client Characteristic Configuration descriptor to notify and/or indicate, but trying either of that results in an exception and a message that notifications should be set on the characteristic itself using setNotifyValue:forCharacteristic: on the peripheral.
My main problem is, that there are no callbacks to peripheral:didUpdateValueForCharacteristic:error: on Glucose Measurement characteristic including the records. I event tried calling [_peripheral setNotifyValue:YES forCharacteristic:characteristic] again on that characteristic, after requesting the records.
Does anyone see where my error(s) lie? Does anyone achieved (on iOS) what I'm trying to achieve?
Another thing is the BT glucose service specification. I would greatly appreciate, if someone could enlighten me as on how to interpret the responses (means the updated values of the Record Access Control Point characteristic) I get. As I'm not even sure in which order the bytes in the characteristic.value come (e.g. when they are read via getBytes:length: method of NSData).
I think I'm following the process described in the Glucose Profile specification so I'm really at a loss here.
Thank you very much in advance!
Best regards,
Gabriel
Having encountered the same issue, I was unable to work out how to interpret the 06000105 value, however I think that is an error response code of sorts.
What fixed the issue for me was to exclude the Operand if it was null, and only use the Op Code and Operator:
char buffer[2];
// Op Code: 0x01 report stored records
buffer[0] = 0x01;
// Operator: 0x01 All records, 0x06 last one
buffer[1] = 0x01;
NSData *data = [NSData dataWithBytes:buffer length:2];
...
Then all the records came flowing in as expected in didUpdateValueForCharacteristic

Detecting Color of iPhone/iPad/iPod touch?

Is there any way or hack to detect on what color (black / white) iPhone, iPad or iPod touch the iOS is installed?
I want to load corresponding UI skins in case of Black or White devices.
There's a private API to retrieve both the DeviceColor and the DeviceEnclosureColor.
UIDevice *device = [UIDevice currentDevice];
SEL selector = NSSelectorFromString(#"deviceInfoForKey:");
if (![device respondsToSelector:selector]) {
selector = NSSelectorFromString(#"_deviceInfoForKey:");
}
if ([device respondsToSelector:selector]) {
NSLog(#"DeviceColor: %# DeviceEnclosureColor: %#", [device performSelector:selector withObject:#"DeviceColor"], [device performSelector:selector withObject:#"DeviceEnclosureColor"]);
}
I've blogged about this and provide a sample app:
http://www.futuretap.com/blog/device-colors/
Warning: As mentioned, this is a private API. Don't use this in App Store builds.
The answer to the question is NO (as of now) and personally I don't think it's worth much, because what if the end-user uses a skin or an additional casing for his iPhone?
I'd suggest to initially ask the user "Hey, what's the color of your phone?" and then do accordingly.
Additionally, a research provided me with this information, I'm not sure if it's TRUE or if is going to help you.
The serial number is the key :)
If aabccdddeef is the serial number of the iPhone 4, ee represents the Color, (A4=black). I hope some of you here check this information with yours to see if this is true.
Just my 2 cents worth - if anyone is looking for the iPhone 5c colors, the colors below are picked from the apple website.
Hope it is of use to anyone:-)
iPhone 5c Colors:
Green
R 179
G 243
B 142
HEX #B3F38E
Blue
R 123
G 195
B 252
HEX #7BC3FC
Yellow
R 255
G 243
B 141
HEX #FFF38D
Red
R 252
G 132
B 142
HEX #FF848E
White
R 239
G 239
B 239
HEX #EFEFEF
According to information sprinkled around the web, the color of the device is encoded in the serial number. iFixit's blog indicates that the third- and second-to-last positions hold the information: xxxxxxxxCCx For an iPhone 4, A4 indicates black. No one seems to have the code for a white iPhone 4, which is strange. One forum posting indicates that it might be DZ. Everyone seems to be just parroting everyone else's information here.
Another site, mydigitallife.com, has an article listing the color codes for various older models. In some cases, the three positions have to be read together in order to determine the color. According to this site, all iPhone 3Gs models have 3N in the color code position; 3NP indicates "Black 16GB 3Gs", and 3NQ indicates "White 16GB 3Gs". The original (2G) iPhone also uses all three positions to indicate size (there were no color options).
There are already a number of questions here on SO that will help you to get the device's serial number.
For debugging purposes I compiled a more comprehensive list of of possible deviceInfoForKey: keys.
Interesting keys to note (for this question) are DeviceRGBColor DeviceEnclosureRGBColor. The values appear to be an integer that represent the RGB value in the form 0x00rrggbb.
Here, for reference, are all the keys I found:
ActiveWirelessTechnology
AirplaneMode
assistant
BasebandCertId
BasebandChipId
BasebandPostponementStatus
BasebandStatus
BatteryCurrentCapacity
BatteryIsCharging
BluetoothAddress
BoardId
BootNonce
BuildVersion
CertificateProductionStatus
CertificateSecurityMode
ChipID
CompassCalibrationDictionary
CPUArchitecture
DeviceClass
DeviceColor
DeviceEnclosureColor
DeviceEnclosureRGBColor
DeviceName
DeviceRGBColor
DeviceSupportsFaceTime
DeviceVariant
DeviceVariantGuess
DiagData
dictation
DiskUsage
EffectiveProductionStatus
EffectiveProductionStatusAp
EffectiveProductionStatusSEP
EffectiveSecurityMode
EffectiveSecurityModeAp
EffectiveSecurityModeSEP
FirmwarePreflightInfo
FirmwareVersion
FrontFacingCameraHFRCapability
HardwarePlatform
HasSEP
HWModelStr
Image4Supported
InternalBuild
InverseDeviceID
ipad
MixAndMatchPrevention
MLBSerialNumber
MobileSubscriberCountryCode
MobileSubscriberNetworkCode
ModelNumber
PartitionType
PasswordProtected
ProductName
ProductType
ProductVersion
ProximitySensorCalibrationDictionary
RearFacingCameraHFRCapability
RegionCode
RegionInfo
SDIOManufacturerTuple
SDIOProductInfo
SerialNumber
SIMTrayStatus
SoftwareBehavior
SoftwareBundleVersion
SupportedDeviceFamilies
SupportedKeyboards
telephony
UniqueChipID
UniqueDeviceID
UserAssignedDeviceName
wifi
WifiVendor
As others have noted, no, there is no official way of getting this information. Apple clearly knows (look in iTunes when you sync), so they could make it available. Might be worth raising a Radar.

How do I detect a dual core CPU on iOS?

My app uses an NSOperationQueue to cache thumbnail images in a background thread. On the iPad2 I can push the concurrent task count limit up to 5 or 6, but on single core devices like the iPad 1 this brings the UI to a grinding halt.
So, I'd like to detect a dual core device (currently only iPad 2) and adapt the concurrent limit appropriately. I know I'm not supposed to check model numbers, rather device features. So what device feature should I be looking for that would tell me whether the cpu is dual core?
Method 1
[[NSProcessInfo processInfo] activeProcessorCount];
NSProcessInfo also has a processorCount property. Learn the difference here.
Method 2
#include <mach/mach_host.h>
unsigned int countCores()
{
host_basic_info_data_t hostInfo;
mach_msg_type_number_t infoCount;
infoCount = HOST_BASIC_INFO_COUNT;
host_info( mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount ) ;
return (unsigned int)(hostInfo.max_cpus);
}
Method 3
#include <sys/sysctl.h>
unsigned int countCores()
{
size_t len;
unsigned int ncpu;
len = sizeof(ncpu);
sysctlbyname ("hw.ncpu",&ncpu,&len,NULL,0);
return ncpu;
}
Just use:
[[NSProcessInfo processInfo] processorCount]
I guess this needs a separate answer rather than a comment:
I wonder what does the number of cores means now that apple brought more asymmetric processing with A10 fusion? Do we have 2.2 cores or 4 cores? apple neglected to make activeProcessorCount float to account for it's fractal nature. note it was like so even before fusion cause they likely had thermal throttling back then. They need either fix overcomittal of nsoperationqueue or come up with a float equivalent for activeProcessorCount and deprecate the activeProcessorCount in its current form that is losing its utility in the face of recent hw advancements
So the faster the Moore's law falls into oblivion or receives a shiny new constant
the more meaningless core counting becomes. Unless you are writing some sort
of a Geek Bench 42, multicore score edition.
Living in the late 2016, to address the underlying issue you are facing rather than hacking through with max concurrent operation prop I assume
you have adjusted the QoS for the NSOperationQueue to .Background?
Me thinks this is a cleaner way to solve your problem with modern
ios sdk then counting 'em cores using miles of rope courtesy of albertamg
Also please take a look at
NSProcessInfoThermalStateDidChangeNotification (macos) and NSProcessInfo.lowPowerModeEnabled (ios)
(I guess an alternative to observing NSProcessInfoThermalStateDidChangeNotification
is to KVo on activeProcessorCount new value)
if you start to account for those new realities, the magic constants adjustments
for multiplying core count would get interesting very fast...
and rot as the new hardware rolls out of cupertino.
And it will be just about as easy to get it right on the current
zoo of Apple hw as to get socket-level networking working correctly:
doable, but by select few in Cupetino with iSteve shadow
looming over the shoulder checking quality ;-)
In Swift you can detect / print the number of active processors with the following code:
let processInfo = ProcessInfo()
print(processInfo.activeProcessorCount)
This code does not need any extra header files or frameworks and works completely natively.
Among other things, you can get that information through a system call...
NSDictionary dictionaryWithObjectsAndKeys:
[self machineType],#"MachineType",
[self humanMachineType],#"HumanMachineType",
[self powerPCTypeString],#"ProcessorType",
[NSNumber numberWithLong:
[self processorClockSpeed]],
#"ProcessorClockSpeed",
[NSNumber numberWithLong:
[self processorClockSpeedInMHz]],
#"ProcessorClockSpeedInMHz",
[NSNumber numberWithInt:[self countProcessors]],
#"CountProcessors",
[self computerName],#"ComputerName",
[self computerSerialNumber],#"ComputerSerialNumber",
[self operatingSystemString],#"OperatingSystem",
[self systemVersionString],#"SystemVersion",
nil];
Here's the reference...
http://cocoadev.com/HowToGetHardwareAndNetworkInfo
I guess:
sysctl(HW_NCPU)
or
sysctlbyname("hw.ncpu", NULL, &size, NULL, 0);
should work.
you can modify code from: Detect the specific iPhone/iPod touch model
Swift 5
To obtain logical cores count use this snippet:
let logicalCoresCount = ProcessInfo.processInfo.processorCount
To obtain physical cores count use below one:
func physicalCoresCount() -> UInt {
var size: size_t = MemoryLayout<UInt>.size
var coresCount: UInt = 0
sysctlbyname("hw.physicalcpu", &coresCount, &size, nil, 0)
return coresCount
}

Resources