How to get users mail addresses on OS X Lion? - cocoa

I was getting the users mail addresses from Libraray/Preferences/com.apple.mail.plist. They are not there any more in Lion :P Do I have to use scripting bridge? Any hints? Thanks

I would get them right out of Address Book. That should work regardless of what email app is being used.
// Find 'me' card in address book.
ABPerson* meCard = [[ABAddressBook sharedAddressBook] me];
if( meCard == nil ) {
NSLog( #"Could not find me!" );
return;
}
// Get my email addresses.
ABMultiValue* anEmailList = [meCard valueForProperty:kABEmailProperty];
if( anEmailList == nil ) {
NSLog( #"I have no email!" );
return;
}
// Output them.
for( NSUInteger index = 0; index < [anEmailList count]; index++ ) {
NSString* aLabel = [anEmailList labelAtIndex:index];
NSString* aValue = [anEmailList valueAtIndex:index];
NSLog( #"%#: %#", aLabel, aValue );
}

Mail in Lion stores the equivalent in ~/Library/Mail/V2/MailData/Accounts.plist. Note however that you are assuming that the user uses the Apple Mail program, unless that's what you really need you may want to have alternative methods for getting the address. You may for instance depending on how the system has been set up use the CSIdentity APIs, such as CSIdentityGetEmailAddress().

Apple script will get the job done.

Related

HomeKit HMService serviceType issue

I have two lighbulb-type accessories enabled on the Accessory Simulator. When I try to read the serviceType of HMService, it returns something like:
0000003E-0000-1000-8000-0026BB765291 instead of HMServiceTypeLightbulb
for (int i = 0; i < [homeKitController.accessories count]; i++) {
HMAccessory *accessory = [homeKitController.accessories objectAtIndex:i];
NSArray *services = accessory.services;
for (int i = 0; i < [services count]; i++) {
HMService *service = [services objectAtIndex:i];
NSLog(#"%#", service.serviceType);// <-returns 0000003E-0000-1000-8000-0026BB765291
}
}
The exact code above was working during Xcode beta 1 (before Xcode 6 GM came out). It used to print out the type of the service as a NSString. Now it prints this odd value. Any ideas or thoughts are appreciated.
HMServiceTypeLightbulb is a string constant, and is defined as that hex string you provided. The HomeKit system of accessories/services/characteristics mimics how BLE works, probably to simplify the implementation of BLE HomeKit accessories. The long hex string is the same format as a BLE UUID. When looking for a specific service, just check string equality on the HMxxx constants provided by HomeKit.

How to access finder sidebar shared content in cocoa

I want to access the shared content of left sidebar of finder in mac, so that i can get the system list connected to the same network. I can access favorite content, but could not get succeeded to access.
I am using this code to access favorite content of finder.
UInt32 seed;
LSSharedFileListRef sflRef = LSSharedFileListCreate(NULL,
kLSSharedFileListFavoriteItems,
NULL);
CFArrayRef items = LSSharedFileListCopySnapshot( sflRef, &seed );
for( size_t i = 0; i < CFArrayGetCount(items); i++ )
{
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(items, i);
if( !item )
continue;
CFURLRef outURL = NULL;
LSSharedFileListItemResolve( item, kLSSharedFileListNoUserInteraction, (CFURLRef*) &outURL, NULL );
if( !outURL )
continue;
//The actual path string of the item
CFStringRef itemPath = CFURLCopyFileSystemPath(outURL,kCFURLPOSIXPathStyle);
// TODO: Do whatever you want to do with your path here!!!!
CFRelease(outURL);
CFRelease(itemPath);
}
CFRelease(items);
CFRelease(sflRef);
Since i want to access systems available in shared network i change the key according to the key in the header file
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.fram‌​ework/Headers/LSSharedFileList.h
But i get nothing for shared content.
Can anyone help me for accessing this.
Thanks for your time to help me in advance.
You can use kLSSharedFileListRecentServerItems to get Recently connected network volumes.

IOServiceGetMatchingServices does not find some devices on some Macs

I have an issue with an app that monitors the USB bus for changes. Specifically if I want to get a list of attached USB sevices, I am using the code below. What is strange is that some users (and nautally not my machines) do not see one or two devices.
Those devices DO show up in the IORegistryExplorer, and show registered.
The machines for which this is not working are also running 10.6 and are also MacBook Pros.
CFMutableDictionaryRef service_properties = CFDictionaryCreateMutable(NULL, 0, NULL,NULL);
CFMutableDictionaryRef child_props = CFDictionaryCreateMutable(NULL, 0, NULL,NULL);
kr = IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceNameMatching("AppleUSBEHCI"), &io_objects);
if(kr != KERN_SUCCESS)
exit(1);
while((io_service= IOIteratorNext(io_objects)))
{
kr = IORegistryEntryCreateCFProperties(io_service, &service_properties, kCFAllocatorDefault, kNilOptions);
io_iterator_t iter;
kr = IORegistryEntryGetChildIterator(io_service, kIOServicePlane, &iter);
io_registry_entry_t child;
while( (child = IOIteratorNext( iter )))
{
kr = IORegistryEntryCreateCFProperties(child, &child_props, kCFAllocatorDefault, kNilOptions );
NSLog(#"%#",child_props);
}
IOObjectRelease(io_service);
}
You're matching on entirely the wrong thing. You're matching against the physical controller used in the Mac (EHCI, UHCI, OHCI). This will fail whenever they invent a new controller standard, such as XHCI in new Macs since 2012 (for USB 3 compatibility).
What you probably want to do is to match against IOUSBDevice, that what I do when I want to match every device in the system. This is also how its done in the Deva sample code.
It turns out that you need to poll all the bus types:
for(i=0;i<3;i++){
if(i==0)kr = IOServiceGetMatchingServices(myMasterPort,
IOServiceNameMatching("AppleUSBEHCI"), &io_objects);
if(i==1)kr = IOServiceGetMatchingServices(myMasterPort,
IOServiceNameMatching("AppleUSBOHCI"), &io_objects);
if(i==2)kr = IOServiceGetMatchingServices(myMasterPort,
IOServiceNameMatching("AppleUSBUHCI"), &io_objects);
if(kr != KERN_SUCCESS)
exit(1);
I agree with Jeremy : there are other possibilities than AppleUSBEHCI
Maybe you probably know that (just in case):
ioreg -l | grep AppleUSB
should show the alive USB status on your machine

How can I move/resize windows programmatically from another application?

I know, that I can use Apple Event Object Model for moving and resizing windows of Cocoa applications. But what can I use for Carbon applications?
Peter was right, you can access to bounds of any window using the following AppleScript:
tell application "System Events"
set allProcesses to application processes
repeat with i from 1 to count allProcesses
tell process i
repeat with x from 1 to (count windows)
position of window x
size of window x
end repeat
end tell
end repeat
end tell
You can also use the Accessibility API. This is how I think Optimal Layout is doing it.
First you have make sure your app has permission to use it.
BOOL checkForAccessibility()
{
NSDictionary *options = #{(__bridge id) kAXTrustedCheckOptionPrompt : #YES};
return AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef) options);
}
Next, use the NSWorkspace::RunningApplications to get the PID of the app whose window you want to manipulate.
NSArray<NSRunningApplication *> *runningApps =[[NSWorkspace sharedWorkspace] runningApplications];
for( NSRunningApplication *app in runningApps )
{
if( [app bundleIdentifier] != nil && [[app bundleIdentifier] compare:#"IdentifierOfAppYouWantToFindHere"] == 0 )
{
PID = [app processIdentifier];
}
}
Then use the PID to get access to the main window reference using the Accessibility API.
AXUIElementRef app = AXUIElementCreateApplication( PID );
AXUIElementRef win;
AXError error = AXUIElementCopyAttributeValue( app, kAXMainWindowAttribute, ( CFTypeRef* )&win );
while( error != kAXErrorSuccess ) // wait for it... wait for it.... YaY found me a window! waiting while program loads.
error = AXUIElementCopyAttributeValue( app, kAXMainWindowAttribute, ( CFTypeRef* )&win );
Now you can set the size and position using something like this:
CGSize windowSize;
CGPoint windowPosition;
windowSize.width = width;
windowSize.height = height;
windowPosition.x = x;
windowPosition.y = y;
AXValueRef temp = AXValueCreate( kAXValueCGSizeType, &windowSize );
AXUIElementSetAttributeValue( win, kAXSizeAttribute, temp );
temp = AXValueCreate( kAXValueCGPointType, &windowPosition );
AXUIElementSetAttributeValue( win, kAXPositionAttribute, temp );
CFRelease( temp );
CFRelease( win );
Same thing. You can use Apple Events on any scriptable application, and Apple Events and scriptability are a lot older than Carbon.

Finding DNS server settings programmatically on Mac OS X

I have some cross platform DNS client code that I use for doing end to end SMTP and on windows I can find the current DNS server ip addresses by looking in the registry. On the Mac I can probably use the SystemConfiguration framework as mentioned in the first answer, however the exact method of doing so is not immediately obvious.
For instance SCDynamicStoreCopyDHCPInfo returns some of the dynamic DHCP related data but not the DNS server addresses.
I know its very late to answer this question but may be helpful for the others.
This Code will help out for this task ..
SCPreferencesRef prefsDNS = SCPreferencesCreate(NULL, CFSTR("DNSSETTING"), NULL);
CFArrayRef services = SCNetworkServiceCopyAll(prefsDNS);
long servicesCount = CFArrayGetCount(services);
for (long i = 0; i < servicesCount; i++) {
const SCNetworkServiceRef service = (const SCNetworkServiceRef)CFArrayGetValueAtIndex(services, i);
CFStringRef interfaceServiceID = SCNetworkServiceGetServiceID(service);
CFStringRef primaryservicepath = CFStringCreateWithFormat(NULL,NULL,CFSTR("State:/Network/Service/%#/DNS"),interfaceServiceID);
SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, CFSTR("DNSSETTING"), NULL, NULL);
CFPropertyListRef propList = SCDynamicStoreCopyValue(dynRef,primaryservicepath);
if (propList) {
CFDictionaryRef dict = (CFDictionaryRef)propList;
CFArrayRef addresses = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("ServerAddresses"));
long addressesCount = CFArrayGetCount(addresses);
for (long j = 0; j < addressesCount; j++) {
CFStringRef address = (CFStringRef)CFArrayGetValueAtIndex(addresses, j);
// Print address
CFShow(address);
}
CFRelease(propList);
}
CFRelease(dynRef);
CFRelease(primaryservicepath);
}
CFRelease(services);
CFRelease(prefsDNS);
I know it's been a long time since you needed this, but there is nothing worse than a old unsolved answer. You can't access them from "/etc/resolv.conf" because of permission issues. After much searching, and a little luck I discovered you can get it via res_ninit() function.
// Get native iOS System Resolvers
res_ninit(&_res);
res_state res = &_res;
for (int i = 0; i < res->nscount; i++) {
sa_family_t family = res->nsaddr_list[i].sin_family;
int port = ntohs(res->nsaddr_list[i].sin_port);
if (family == AF_INET) { // IPV4 address
char str[INET_ADDRSTRLEN]; // String representation of address
inet_ntop(AF_INET, & (res->nsaddr_list[i].sin_addr.s_addr), str, INET_ADDRSTRLEN);
} else if (family == AF_INET6) { // IPV6 address
char str[INET6_ADDRSTRLEN]; // String representation of address
inet_ntop(AF_INET6, &(res->nsaddr_list [i].sin_addr.s_addr), str, INET6_ADDRSTRLEN);
}
}
res_ndestroy(res);
You can use the SystemConfiguration framework. It's in C.
Update: apparently the rest of the web is harder to use than I thought. Search for the key "State:/Network/Service/ServiceID/DNS" where ServiceID is the ID of the service.
They are also available from
/etc/resolv.conf
You could read from /etc/resolv.conf.

Resources