I'm using AVAudioSession to see which route I'm on at the moment.
Now, looking at the output response I see something like this:
<AVAudioSessionPortDescription: 0x28263c1c0, type = BluetoothA2DPOutput; name = FreeBuds Lite; UID = E4:34:93:3C:4B:5F-tacl; selectedDataSource = (null)>
According to Apple's documentation the UID is A system-assigned unique identifier (UID) for the port. I wanted to know if it means that for each different device the number will be different (so far its seems it is) and also that for the same device the number will be presistent an won't change over time?
Related
I want to check which Bluetooth Devices my iPhone is connected to. In order to do that, I use CBCentralManager.retrieveConnectedPeripherals() like this:
let connectedPerphs = centralManager.retrieveConnectedPeripherals(withServices: []);
My problem is that even if my iPhone is connected to a BluetoothDongle (it explicitly says "connected" in the settings), the list that is returned by retriveConnectedPeripherals() is always empty. Am I using the method in a wrong way or can it not be used to detect a bluetooth connection such as the connection to to my dongle? If the latter is the case, how can I detect that connection?
Let me clear, centralManager.retrieveConnectedPeripherals always return empty or nil value, If you are not passing any value into serviceUUIDs
retrieveConnectedPeripherals(withServices:)
Returns a list of the peripherals (containing any of the specified
services) currently connected to the system.
serviceUUIDs:
A list of service UUIDs (represented by CBUUID objects).
Update:
Unfortunately this the long way to do it. You can create Array of CBUUID statically then you can pass it to the method. Please refer below code.
let aryUUID = ["1800","18811"]
var aryCBUUIDS = [CBUUID]()
for uuid in aryUUID{
let uuid = CBUUID(string: "1800")
aryCBUUIDS.append(uuid)
}
let connectedPerphs = centralManager.retrieveConnectedPeripherals(withServices: aryCBUUIDS)
List of available services
First, this works only with BLE devices, thus if your dongle is using a common BT you will not get it from here, but probably using EAAccessoryManager var connectedAccessories: [EAAccessory] method, but as far as I know your app must comply to MFI.
That is why is asking which service your devices are exposing as a filter.
The IotfDevice Class in Quarks has a constructor with an optionsFile. What is the format of this file and what are the necessary values?
The options file has five values: org, type, id, auth-method, auth-token. This is an example of mine with the values obfuscated.
[device]
org = 4pj4r4
type = rustQuark
id = rustIIa
auth-method = token
auth-token = 8jLWEY(P4SVJl5oi!V
When you register a device the set of values are issued, details and examples can be found here.
A little context.
Internet of Things Foundation (IoTf) is an infrastructure for application's to communicate with devices. IoTf requires that you register the application and all
devices that send data to the application.
Why would you use IoTf? Getting the communication setup between devices is
a pain: firewalls, retry, failover, QoS, debugging, monitoring. This is facility especially nice if you're doing a proof of concept.
For a better description of IoTf look here.
I am trying to create an ios application and I want to segment the users based on the data providers they are using, such as Verizon and AT&T. Is it possible to get this information programmatically from the ios application.
You should check the CTCarrier.
Just import CoreTelephony into your Swift file.
Then you can use the carrierName property to get the name of your carrier.
// Setup the Network Info and create a CTCarrier object
let networkInfo = CTTelephonyNetworkInfo()
let carrier = networkInfo.subscriberCellularProvider
// Get carrier name
let carrierName = carrier.carrierName
Now that you can have multiple SIM cards, subscriberCellularProvider is deprecated in favor of serviceSubscriberCellularProviders. You can get an array of the providers with this:
let carriers = CTTelephonyNetworkInfo().serviceSubscriberCellularProviders?.values
In my case, I was checking to see if the user has an American phone number so they can text support instead of email. You can do that with this:
carriers.contains { $0.isoCountryCode?.lowercased() == "us" }
On my phone, I only have one SIM card, but this array returns two values and one has all nil properties so be sure to handle that if you are inspecting them.
You will want to use the CTCarrier carrierName in the CoreTelephony framework: https://developer.apple.com/library/prerelease/ios/documentation/NetworkingInternet/Reference/CTCarrier/index.html#//apple_ref/occ/instp/CTCarrier/carrierName
I've noticed this error in my console log for a while. Though it does not affect the execution of my application, I find it really annoying. Thus, I started to trace where this error came from. It turns out when I call availableInputs
NSArray *inputs = [[AVAudioSession sharedInstance] availableInputs];
It will give me the log message:
ERROR: [0x3d61318c] AVAudioSessionPortImpl.mm:50: ValidateRequiredFields: Unknown selected data source for Port iPhone Microphone (type: MicrophoneBuiltIn)
I tried to print out the inputs..
Printing description of inputs:
<__NSArrayI 0x188c4610>(
<AVAudioSessionPortDescription: 0x188c4580, type = MicrophoneBuiltIn; name = iPhone Microphone; UID = Built-In Microphone; selectedDataSource = (null)>,
<AVAudioSessionPortDescription: 0x18835d90, type = BluetoothHFP; name = Valore-BTi22; UID = 00:23:01:10:38:77-tsco; selectedDataSource = (null)>
So selectedDataSource is (null). I don't know what should I do to make it not null? iPhone Microphone is a built-in input... I suppose it's set by Apple already?
This problem seems not just happen to me... I will just share my understanding here..
My situation is.. I'm using pjsip library, which has a lower level control of audio resources. I've noticed that, the sound device has been closed before I call [[AVAudioSession sharedInstance] availableInputs];
Thus, (I guess) AVAudioSession, as a higher level control, couldn't find corresponding audio data source for its input - as the error indicated...
To further investigate the problem, you'd better check somewhere in your code that modify the audio source.. and make sure the audio source is activated before you call AVAudioSession
I can only go this far for now... Deeper understanding and better explanation of audio control is always appreciated!!
Regarding the error in your console, I can also confirm that I sometimes receive this message when using my iPhone 5S, but I've never seen it on my 4S. It could just be some core audio dump, but it doesn't seem to affect actual performance (at least for me).
Regarding the available inputs, what your actually printing out is the available input ports and their descriptions. This bit is more confusing and I don't understand why the selectedDataSource field is null for each one.
I will say that the iPhone is definitely defaulting to one of those sources (probably the Built-in Mic) regardless of what the selectedDataSource is saying.
Now if you wanted to explicitly select one of the port descriptions you could do something like this:
NSArray *availableInputs = [[AVAudioSession sharedInstance] availableInputs];
AVAudioSessionPortDescription *port = [availableInputs objectAtIndex:0]; //built in mic for your case
NSError *portErr = nil;
[[AVAudioSession sharedInstance] setPreferredInput:port error:&portErr];
and I would check portErr afterwards to make sure there's no error in setting the preferredInput.
Its worth noting that you can also cycle through the available dataSources for a particular Port Description as well and select one using
[port setPreferredDataSource:source error:&sourceErr];
then follow that with:
[[AVAudioSession sharedInstance] setPreferredInput:port error:&portErr];
These are some handy iOS7 only features that take advantage of hardware with multiple built-in mice.
The iPhone 5 has three microphones - top front, top back, and bottom. I would like to record on all of them at the same time to do some signal processing. I've tried for several days unsuccessfully.
Using AVAudioSession, I can see the microphones:
NSLog(#"%#", [AVAudioSession sharedInstance].availableInputs);
"<AVAudioSessionPortDescription: 0x14554400, type = MicrophoneBuiltIn; name = iPhone Microphone; UID = Built-In Microphone; selectedDataSource = Back>"
NSLog(#"%#", [AVAudioSession sharedInstance].availableInputs[0].inputDataSources);
"<AVAudioSessionDataSourceDescription: 0x145afb00, ID = 1835216945; name = Bottom>",
"<AVAudioSessionDataSourceDescription: 0x145b1870, ID = 1835216946; name = Front>",
"<AVAudioSessionDataSourceDescription: 0x145b3650, ID = 1835216947; name = Back>"
I can use AVAudioSessionPortDescription -setPreferredDataSource:error: to record from one of the three. But I cannot record on more than one simultaneously. If I set the number of input channels to 2, I get two identical tracks from the same microphone.
AVAudioRecorder has a property channelAssignments which seems like it should work, but AVAudioSession inputNumberOfChannels and maximumInputNumberOfChannels are both 1. The property channelAssignments is designed for auxiliary microphones which have multiple channels.
I tried using the low-level AudioUnit, but I get the same result. I could not find any properties on AudioUnit to change the input source.
Any help would be appreciated.
My understanding, after all my research trying to do the same thing, is just what you've described - you can't prefer multiple data sources for the one device, thus you can't record from multiple built-in mics at once. If anyone can prove me wrong, I'd VERY much love to hear it!
Sidenote: I can't seem to run your code. As written, I get
Property availableInputs not found on object of type 'id'
Even after massaging what you've got into a format that doesn't require any explicit casts:
NSLog(#"%#", [[[AVAudioSession sharedInstance] availableInputs][0] inputDataSources]);
I get SIGABRT:
-[AVAudioSessionPortDescription inputDataSources]: unrecognized selector sent to instance 0xd59dbe0'
what SDK are you using that your code actually compiles, much less runs?