How to distinguish MacBook and Mac desktops programmatically? - objective-c

I'm working on a Mac app that should distinguish MacBook and Mac desktops (iMac/Mac Pro).
I think I can get it done with model number. Then how I can get the model number? And which letter indicates it's a notebook or desktop? Or is there any other easier or better way?

You can use this little program. NSLog the output to test it.
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
+ (NSString *)machineModel
{
size_t length = 0;
sysctlbyname("hw.model", NULL, &length, NULL, 0);
if (length) {
char *m = malloc(length * sizeof(char));
sysctlbyname("hw.model", m, &length, NULL, 0);
NSString *model = [NSString stringWithUTF8String:m];
free(m);
return model;
}
return #"Unknown model";
}
It will provide the same output as entering sysctl hw.model on the terminal.

You haven't specified a language, but from Terminal sysctl hw.model will return with an identifier for the current Mac. For example, on my computer it returns MacBookPro5,5.

Related

OpenACC; copy_in not working?

I have this sample code:
#include <stdio.h>
#include <stdlib.h>
#ifdef _OPENACC
#include <openacc.h>
#endif
#define N 1000
int main() {
#ifdef _OPENACC
acc_init(acc_device_not_host);
printf(" Compiling with OpenACC support \n");
#endif
double * a;
int n = 100;
a = (double *) malloc(n * sizeof(double));
for (int i = 0; i < n; i++)
a[i] = 1.0f;
#pragma acc data copy_in(a[0:n])
{
#pragma acc kernels loop
for (int i = 0; i < n; i++)
a[i] = (double) i + a[i];
}
#ifdef _OPENACC
acc_shutdown(acc_device_not_host);
#endif
printf("Value of a[10]: %lf\n", a[10]);
return 0;
}
Teacher told me that the output is 1.0, because I have copy_in; then, a is copied on the acceñeratpr, but when it ends, a contains 1.0 in every position; but if I run this code I get 11.0, why?
There's a couple of things going on here. First, the correct clause is copyin (no underscore). Second, since you're only copying the input values into the region, any changes made within the data region will not come back to the CPU, so unless you're running this on a shared memory system, for example running on a multicore CPU, then the value of a at your printf statement will be like that loop never ran. In order to get the results back from the data region, you'll actually want a copy clause instead. That informs the compiler to copy in the input values to the region and copy out the output values from the region.
Since you're getting 11, clearly the loop is getting run somewhere. What compiler are you using and what flags? Either you're not actually building with OpenACC enabled or you're running on a shared memory target and your teacher isn't.

Cannot get UDP socket to Bind

I have been trying for two weeks to send a character via UDP. So far I have not been able to find an example that actually works using XCode and IOS 7. I am currently stuck as every time I run my code the Bind function returns a -1. I have no clue as to what is wrong or what the solution is. PS. I know my to Address is missing but for now I am just trying to get by the Bind issue. (Examples to use a specific address have failed to compile.)
This is very frustration as I have successfully create UPD programs on Windows, Windows Mobile 6.0, and AS400 without as much effort as I have had to spend on this and so far nothing to show.
Here is my current code
char Buff[256];
strcpy(Buff,"Test MESSAGE");
int handle = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (handle > 0) {
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(311);
inet_pton(AF_INET, "10.121.8.54", &(address.sin_addr));
if (bind(handle,(struct sockaddr *) &address, sizeof(struct sockaddr_in))< 0){
printf("************************ Failed to bind\n");
} else {
send(handle, Buff, sizeof(Buff), 0);
}
} else {
printf("Faile to create socket\n");
}//end if
Here are my imports
#import <sys/socket.h>
#import <netinet/in.h>
#import <sys/types.h>
#import <fcntl.h>
#import <netdb.h>
#import <arpa/inet.h>

Get the boot time in objective c

how can i get the boot time of ios in objective c ?
Is there a way to get it?
Don't know if this will work in iOS, but in OS X (which is essentially the same OS) you would use sysctl(). This is how the OS X Unix utility uptime does it. Source code is available - search for "boottime".
#include <sys/types.h>
#include <sys/sysctl.h>
// ....
#define MIB_SIZE 2
int mib[MIB_SIZE];
size_t size;
struct timeval boottime;
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
size = sizeof(boottime);
if (sysctl(mib, MIB_SIZE, &boottime, &size, NULL, 0) != -1)
{
// successful call
NSDate* bootDate = [NSDate dateWithTimeIntervalSince1970:boottime.tv_sec];
}
The restricted nature of programming in the iOS sandboxed environment might make it not work, I don't know, I haven't tried it.
I took JeremyP's answer, gave the result the full microsecond precision, clarified the names of local variables, improved the order, and put it into a method:
#include <sys/types.h>
#include <sys/sysctl.h>
// ....
+ (nullable NSDate *)bootDate
{
// nameIntArray and nameIntArrayLen
int nameIntArrayLen = 2;
int nameIntArray[nameIntArrayLen];
nameIntArray[0] = CTL_KERN;
nameIntArray[1] = KERN_BOOTTIME;
// boot_timeval
struct timeval boot_timeval;
size_t boot_timeval_size = sizeof(boot_timeval);
if (sysctl(nameIntArray, nameIntArrayLen, &boot_timeval, &boot_timeval_size, NULL, 0) == -1)
{
return nil;
}
// bootSince1970TimeInterval
NSTimeInterval bootSince1970TimeInterval = (NSTimeInterval)boot_timeval.tv_sec + ((NSTimeInterval)boot_timeval.tv_usec / 1000000);
// return
return [NSDate dateWithTimeIntervalSince1970:bootSince1970TimeInterval];
}

Programmatically detect whether an iPad has Retina display?

How can I programmatically (Objective-C) whether an iPad has a Retina display?
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && [[UIScreen mainScreen] respondsToSelector:#selector(scale)] && [UIScreen mainScreen].scale > 1)
{
// new iPad
}
As other posters have answered, you should check for features rather than models. However, in the few obscure cases where you might want to identify a particular model, you can use the hw.machine sysctrl as follows. Note that if you can't identify the model, it's most likely because your code is running on a new model, so you should do something sensible in that case.
#include <sys/types.h>
#include <sys/sysctl.h>
// Determine the machine name, e.g. "iPhone1,1".
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0); // Get size of data to be returned.
char *name = malloc(size);
sysctlbyname("hw.machine", name, &size, NULL, 0);
NSString *machine = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
free(name);
Now you can compare "machine" against known values. E.g., to detect iPad (March 2012) models:
if ([machine hasPrefix:#"iPad3,"]) NSLog(#"iPad (March 2012) detected");

Get a list of all available network interfaces (en0, en1, en2, etc) with Cocoa?

In my Cocoa application I want to show the user a list of available network interfaces, like Wireshark does:
What is the best way of getting such a list? Does Apple provide a framework for this, or must I use a C API from the standard library or another library?
Better than wrapping ifconfig you shall check the reference of SCNetworkConfiguration which is part of Core Foundation.
Check SCNetworkInterfaceXxx functions for details.
related answer:
Using Cocoa / Objective-C, get currently connected network's security type in Mac OS X
The following code will get all the interfaces from OS X through System Configuration, then use standard C functions to get the IP addresses (where available).
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define IFT_ETHER 0x6
#include <SystemConfiguration/SCDynamicStore.h>
+(void)getInterfaces
{
SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)#"FindCurrentInterfaceIpMac", NULL, NULL);
CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface"));
id primaryInterface = [(__bridge NSDictionary *)global valueForKey:#"Interfaces"];
for (NSString* item in primaryInterface)
{
if(get_iface_address([item UTF8String]))
{
NSString *ip = [NSString stringWithUTF8String:get_iface_address([item UTF8String])];
NSLog(#"interface: %# - %#",item,ip);
} else
NSLog(#"interface: %#",item);
}
}
static char * get_iface_address (char *interface)
{
int sock;
uint32_t ip;
struct ifreq ifr;
char *val;
if (!interface)
return NULL;
/* determine UDN according to MAC address */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror ("socket");
return NULL;
}
strcpy (ifr.ifr_name, interface);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl (sock, SIOCGIFADDR, &ifr) < 0)
{
perror ("ioctl");
close (sock);
return NULL;
}
val = (char *) malloc (16 * sizeof (char));
ip = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
ip = ntohl (ip);
sprintf (val, "%d.%d.%d.%d",
(ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF);
close (sock);
return val;
}
#include <SystemConfiguration/SCDynamicStore.h>
SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)#"FindCurrentInterfaceIpMac", NULL, NULL);
CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface"));
id primaryInterface = [(__bridge NSDictionary *)global valueForKey:#"Interfaces"];
for (NSString* item in primaryInterface)
{
NSLog(#"%#", item);
}
Your quickest and best bet is to write a wrapper for ifconfig command.