Elysia Tools
Navigation
Objective-C
macOS Mobile Features Objective-C Samples
macOS Objective-C mobile features examples including device information, network status, and system feedback
Samples
Entries inside this sample collection
Device Information
Get device model, system version, hardware information using NSProcessInfo and NSHost
Difficulty
5/10
Estimated time
25 min
Tags
objectivec, macos, device info
Prerequisites
Objective-C basics, Foundation framework
// macOS Objective-C Device Information Examples
// Using Foundation framework
#import <Foundation/Foundation.h>
#import <sys/sysctl.h>
#import <mach/mach.h>
#import <mach/mach_host.h>
// MARK: - 1. System Information
@interface SystemInfo : NSObject
+ (NSString *)getSystemVersion;
+ (NSString *)getSystemBuildVersion;
+ (NSString *)getHostName;
+ (NSString *)getUserName;
+ (NSString *)getDeviceModel;
+ (NSString *)getCPUModel;
+ (NSInteger)getCPUCount;
+ (unsigned long long)getTotalMemory;
+ (unsigned long long)getTotalDiskSpace;
@end
@implementation SystemInfo
+ (NSString *)getSystemVersion {
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
NSOperatingSystemVersion version = processInfo.operatingSystemVersion;
NSString *versionString = [NSString stringWithFormat:@"%ld.%ld.%ld",
(long)version.majorVersion,
(long)version.minorVersion,
(long)version.patchVersion];
NSLog(@"macOS Version: %@", versionString);
return versionString;
}
+ (NSString *)getSystemBuildVersion {
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
NSString *buildVersion = processInfo.operatingSystemVersionString;
NSLog(@"Build Version: %@", buildVersion);
return buildVersion;
}
+ (NSString *)getHostName {
NSString *hostName = [[NSHost currentHost] name];
NSLog(@"Host Name: %@", hostName);
return hostName;
}
+ (NSString *)getUserName {
NSString *userName = NSUserName();
NSLog(@"User Name: %@", userName);
return userName;
}
+ (NSString *)getDeviceModel {
size_t len;
char *model;
sysctlbyname("hw.model", NULL, &len, NULL, 0);
model = malloc(len * sizeof(char));
sysctlbyname("hw.model", model, &len, NULL, 0);
NSString *deviceModel = [NSString stringWithUTF8String:model];
free(model);
NSLog(@"Device Model: %@", deviceModel);
return deviceModel;
}
+ (NSString *)getCPUModel {
size_t len;
char *cpu;
sysctlbyname("machdep.cpu.brand_string", NULL, &len, NULL, 0);
cpu = malloc(len * sizeof(char));
sysctlbyname("machdep.cpu.brand_string", cpu, &len, NULL, 0);
NSString *cpuModel = [NSString stringWithUTF8String:cpu];
free(cpu);
NSLog(@"CPU Model: %@", cpuModel);
return cpuModel;
}
+ (NSInteger)getCPUCount {
NSInteger cpuCount = [[NSProcessInfo processInfo] processorCount];
NSLog(@"CPU Count: %ld", (long)cpuCount);
return cpuCount;
}
+ (unsigned long long)getTotalMemory {
unsigned long long totalMemory = [[NSProcessInfo processInfo] physicalMemory];
NSLog(@"Total Memory: %llu MB (%.2f GB)",
totalMemory / 1024 / 1024,
(double)totalMemory / 1024 / 1024 / 1024);
return totalMemory;
}
+ (unsigned long long)getTotalDiskSpace {
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if (paths.count > 0) {
NSString *documentsPath = paths.firstObject;
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:documentsPath
error:&error];
if (!error) {
unsigned long long totalSpace = [attributes[NSFileSystemSize] unsignedLongLongValue];
unsigned long long freeSpace = [attributes[NSFileSystemFreeSize] unsignedLongLongValue];
NSLog(@"Total Disk Space: %.2f GB", (double)totalSpace / 1024 / 1024 / 1024);
NSLog(@"Free Disk Space: %.2f GB", (double)freeSpace / 1024 / 1024 / 1024);
return totalSpace;
}
}
return 0;
}
@end
// MARK: - 2. Hardware Information
@interface HardwareInfo : NSObject
+ (NSDictionary *)getDetailedSystemInfo;
+ (NSInteger)getActiveCPUCores;
+ (NSInteger)getTotalCPUCores;
+ (NSUInteger)getL1CacheSize;
+ (NSUInteger)getL2CacheSize;
+ (NSUInteger)getL3CacheSize;
+ (double)getCPUFrequency;
@end
@implementation HardwareInfo
+ (NSDictionary *)getDetailedSystemInfo {
NSMutableDictionary *info = [NSMutableDictionary dictionary];
// System info
info[@"systemVersion"] = [SystemInfo getSystemVersion];
info[@"buildVersion"] = [SystemInfo getSystemBuildVersion];
info[@"deviceModel"] = [SystemInfo getDeviceModel];
info[@"cpuModel"] = [SystemInfo getCPUModel];
info[@"cpuCount"] = @([SystemInfo getCPUCount]);
info[@"totalMemory"] = @([SystemInfo getTotalMemory]);
// Host info
info[@"hostName"] = [SystemInfo getHostName];
info[@"userName"] = [SystemInfo getUserName];
// Active cores
info[@"activeCPUCores"] = @([self getActiveCPUCores]);
info[@"totalCPUCores"] = @([self getTotalCPUCores]);
NSLog(@"\n=== Detailed System Info ===");
for (NSString *key in info) {
NSLog(@"%@: %@", key, info[key]);
}
return [info copy];
}
+ (NSInteger)getActiveCPUCores {
host_basic_info_data_t hostInfo;
mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &count);
NSInteger activeCores = hostInfo.avail_cpus;
NSLog(@"Active CPU Cores: %ld", (long)activeCores);
return activeCores;
}
+ (NSInteger)getTotalCPUCores {
host_basic_info_data_t hostInfo;
mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &count);
NSInteger totalCores = hostInfo.max_cpus;
NSLog(@"Total CPU Cores: %ld", (long)totalCores);
return totalCores;
}
+ (NSUInteger)getL1CacheSize {
size_t size;
sysctlbyname("hw.l1icachesize", NULL, &size, NULL, 0);
if (size > 0) {
unsigned long long cacheSize;
sysctlbyname("hw.l1icachesize", &cacheSize, &size, NULL, 0);
NSLog(@"L1 Cache Size: %llu KB", cacheSize / 1024);
return (NSUInteger)cacheSize;
}
return 0;
}
+ (NSUInteger)getL2CacheSize {
size_t size;
sysctlbyname("hw.l2cachesize", NULL, &size, NULL, 0);
if (size > 0) {
unsigned long long cacheSize;
sysctlbyname("hw.l2cachesize", &cacheSize, &size, NULL, 0);
NSLog(@"L2 Cache Size: %llu KB", cacheSize / 1024);
return (NSUInteger)cacheSize;
}
return 0;
}
+ (NSUInteger)getL3CacheSize {
size_t size;
sysctlbyname("hw.l3cachesize", NULL, &size, NULL, 0);
if (size > 0) {
unsigned long long cacheSize;
sysctlbyname("hw.l3cachesize", &cacheSize, &size, NULL, 0);
NSLog(@"L3 Cache Size: %llu KB", cacheSize / 1024);
return (NSUInteger)cacheSize;
}
return 0;
}
+ (double)getCPUFrequency {
unsigned long long freq = 0;
size_t len = sizeof(freq);
sysctlbyname("hw.cpufrequency", &freq, &len, NULL, 0);
double frequencyGHz = (double)freq / 1000000000.0;
NSLog(@"CPU Frequency: %.2f GHz", frequencyGHz);
return frequencyGHz;
}
@end
// MARK: - 3. Process Information
@interface ProcessInfo : NSObject
+ (NSDictionary *)getCurrentProcessInfo;
+ (NSInteger)getProcessID;
+ (NSString *)getProcessName;
+ (NSString *)getExecutablePath;
+ (NSString *)getBundlePath;
+ (NSTimeInterval)getProcessUptime;
+ (double)getCPUUsage;
+ (unsigned long long)getMemoryUsage;
@end
@implementation ProcessInfo
+ (NSDictionary *)getCurrentProcessInfo {
NSMutableDictionary *info = [NSMutableDictionary dictionary];
info[@"processID"] = @([self getProcessID]);
info[@"processName"] = [self getProcessName];
info[@"executablePath"] = [self getExecutablePath];
info[@"bundlePath"] = [self getBundlePath];
info[@"uptime"] = @([self getProcessUptime]);
info[@"cpuUsage"] = @([self getCPUUsage]);
info[@"memoryUsage"] = @([self getMemoryUsage]);
return [info copy];
}
+ (NSInteger)getProcessID {
pid_t pid = [[NSProcessInfo processInfo] processIdentifier];
NSLog(@"Process ID: %d", pid);
return pid;
}
+ (NSString *)getProcessName {
NSString *processName = [[NSProcessInfo processInfo] processName];
NSLog(@"Process Name: %@", processName);
return processName;
}
+ (NSString *)getExecutablePath {
NSString *executablePath = [[NSBundle mainBundle] executablePath];
NSLog(@"Executable Path: %@", executablePath);
return executablePath;
}
+ (NSString *)getBundlePath {
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSLog(@"Bundle Path: %@", bundlePath);
return bundlePath;
}
+ (NSTimeInterval)getProcessUptime {
NSTimeInterval uptime = [[NSProcessInfo processInfo] systemUptime];
NSLog(@"System Uptime: %.0f seconds (%.1f minutes)", uptime, uptime / 60);
return uptime;
}
+ (double)getCPUUsage {
task_thread_times_info_data_t threadInfo;
mach_msg_type_number_t count = TASK_THREAD_TIMES_INFO_COUNT;
kern_return_t kr = task_info(mach_task_self(),
TASK_THREAD_TIMES_INFO,
(task_info_t)&threadInfo,
&count);
if (kr != KERN_SUCCESS) {
return 0.0;
}
double userSeconds = threadInfo.user_time.seconds + (threadInfo.user_time.microseconds / 1000000.0);
double systemSeconds = threadInfo.system_time.seconds + (threadInfo.system_time.microseconds / 1000000.0);
double totalCpuTime = userSeconds + systemSeconds;
NSTimeInterval uptime = [[NSProcessInfo processInfo] systemUptime];
double cpuUsage = uptime > 0 ? (totalCpuTime / uptime) * 100.0 : 0.0;
NSLog(@"CPU Usage: %.1f%%", cpuUsage);
return cpuUsage;
}
+ (unsigned long long)getMemoryUsage {
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&info,
&size);
if (kerr == KERN_SUCCESS) {
unsigned long long memoryUsage = info.resident_size;
NSLog(@"Memory Usage: %.2f MB", (double)memoryUsage / 1024 / 1024);
return memoryUsage;
}
return 0;
}
@end
// MARK: - 4. Environment Information
@interface EnvironmentInfo : NSObject
+ (NSDictionary *)getEnvironmentInfo;
+ (NSString *)getLocalTimeZone;
+ (NSString *)getCalendarIdentifier;
+ (NSLocale *)getCurrentLocale;
+ (NSString *)getPreferredLanguage;
+ (NSArray<NSString *> *)getPreferredLanguages;
@end
@implementation EnvironmentInfo
+ (NSDictionary *)getEnvironmentInfo {
NSMutableDictionary *info = [NSMutableDictionary dictionary];
info[@"timeZone"] = [self getLocalTimeZone];
info[@"calendar"] = [self getCalendarIdentifier];
info[@"locale"] = [self getCurrentLocale].localeIdentifier;
info[@"preferredLanguage"] = [self getPreferredLanguage];
info[@"preferredLanguages"] = [self getPreferredLanguages];
return [info copy];
}
+ (NSString *)getLocalTimeZone {
NSTimeZone *localTimeZone = [NSTimeZone localTimeZone];
NSString *tzName = localTimeZone.name;
NSLog(@"Time Zone: %@", tzName);
return tzName;
}
+ (NSString *)getCalendarIdentifier {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSString *calendarId = calendar.calendarIdentifier;
NSLog(@"Calendar: %@", calendarId);
return calendarId;
}
+ (NSLocale *)getCurrentLocale {
NSLocale *currentLocale = [NSLocale currentLocale];
NSLog(@"Locale: %@", currentLocale.localeIdentifier);
return currentLocale;
}
+ (NSString *)getPreferredLanguage {
NSString *language = [[NSLocale preferredLanguages] firstObject];
NSLog(@"Preferred Language: %@", language);
return language;
}
+ (NSArray<NSString *> *)getPreferredLanguages {
NSArray<NSString *> *languages = [NSLocale preferredLanguages];
NSLog(@"Preferred Languages: %@", languages);
return languages;
}
@end
// MARK: - 5. Screen Information
@interface ScreenInfo : NSObject
+ (NSSize)getMainScreenSize;
+ (NSRect)getMainScreenFrame;
+ (CGFloat)getMainScreenScale;
+ (NSArray<NSScreen *> *)getAllScreens;
+ (NSInteger)getScreenCount;
@end
@implementation ScreenInfo
+ (NSSize)getMainScreenSize {
NSSize screenSize = [NSScreen mainScreen].frame.size;
NSLog(@"Screen Size: %.0fx%.0f", screenSize.width, screenSize.height);
return screenSize;
}
+ (NSRect)getMainScreenFrame {
NSRect frame = [NSScreen mainScreen].frame;
NSLog(@"Screen Frame: %@", NSStringFromRect(frame));
return frame;
}
+ (CGFloat)getMainScreenScale {
CGFloat scale = [NSScreen mainScreen].backingScaleFactor;
NSLog(@"Screen Scale: %.1f", scale);
return scale;
}
+ (NSArray<NSScreen *> *)getAllScreens {
NSArray<NSScreen *> *screens = [NSScreen screens];
NSLog(@"Number of Screens: %lu", (unsigned long)screens.count);
return screens;
}
+ (NSInteger)getScreenCount {
NSInteger count = [NSScreen screens].count;
NSLog(@"Screen Count: %ld", (long)count);
return count;
}
@end
// MARK: - Main Demonstration
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"=== macOS Objective-C Device Information Examples ===\n");
// 1. Basic system information
NSLog(@"--- 1. Basic System Information ---");
[SystemInfo getSystemVersion];
[SystemInfo getSystemBuildVersion];
[SystemInfo getHostName];
[SystemInfo getUserName];
[SystemInfo getDeviceModel];
[SystemInfo getCPUModel];
[SystemInfo getCPUCount];
[SystemInfo getTotalMemory];
[SystemInfo getTotalDiskSpace];
// 2. Detailed hardware information
NSLog(@"\n--- 2. Hardware Information ---");
[HardwareInfo getDetailedSystemInfo];
[HardwareInfo getActiveCPUCores];
[HardwareInfo getTotalCPUCores];
[HardwareInfo getCPUFrequency];
// 3. Process information
NSLog(@"\n--- 3. Process Information ---");
[ProcessInfo getProcessID];
[ProcessInfo getProcessName];
[ProcessInfo getProcessUptime];
[ProcessInfo getCPUUsage];
[ProcessInfo getMemoryUsage];
// 4. Environment information
NSLog(@"\n--- 4. Environment Information ---");
[EnvironmentInfo getEnvironmentInfo];
// 5. Screen information
NSLog(@"\n--- 5. Screen Information ---");
[ScreenInfo getMainScreenSize];
[ScreenInfo getMainScreenScale];
[ScreenInfo getScreenCount];
// Summary
NSLog(@"\n=== Device Information Summary ===");
NSLog(@"macOS %@ on %@", [SystemInfo getSystemVersion], [SystemInfo getDeviceModel]);
NSLog(@"%@ with %ld cores", [SystemInfo getCPUModel], (long)[SystemInfo getCPUCount]);
NSLog(@"%.2f GB RAM, %.2f GHz",
(double)[SystemInfo getTotalMemory] / 1024 / 1024 / 1024,
[HardwareInfo getCPUFrequency]);
NSLog(@"\n=== Device Information Examples Completed ===");
}
return 0;
}Network Status
Check network connection status and reachability using SCNetworkReachability and NSURLSession
Difficulty
6/10
Estimated time
30 min
Tags
objectivec, macos, network
Prerequisites
Objective-C basics, Foundation framework, SystemConfiguration
// macOS Objective-C Network Status Examples
// Using Foundation and SystemConfiguration frameworks
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>
// MARK: - 1. Basic Network Reachability
typedef NS_ENUM(NSInteger, NetworkStatus) {
NetworkStatusNotReachable = 0,
NetworkStatusReachableViaWiFi = 1,
NetworkStatusReachableViaWWAN = 2
};
@interface NetworkReachability : NSObject
+ (NetworkStatus)currentNetworkStatus;
+ (BOOL)isNetworkAvailable;
+ (BOOL)isWiFiConnected;
+ (BOOL)isCellularConnected;
@end
@implementation NetworkReachability
+ (NetworkStatus)currentNetworkStatus {
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (struct sockaddr *)&zeroAddress);
if (!reachability) {
return NetworkStatusNotReachable;
}
SCNetworkReachabilityFlags flags;
BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags);
CFRelease(reachability);
if (!success) {
return NetworkStatusNotReachable;
}
BOOL isReachable = (flags & kSCNetworkReachabilityFlagsReachable) != 0;
BOOL needsConnection = (flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0;
BOOL isWWAN = (flags & kSCNetworkReachabilityFlagsIsWWAN) != 0;
NetworkStatus status = NetworkStatusNotReachable;
if (isReachable && !needsConnection) {
if (isWWAN) {
status = NetworkStatusReachableViaWWAN;
} else {
status = NetworkStatusReachableViaWiFi;
}
}
NSLog(@"Network Status: %ld", (long)status);
return status;
}
+ (BOOL)isNetworkAvailable {
NetworkStatus status = [self currentNetworkStatus];
BOOL available = (status != NetworkStatusNotReachable);
NSLog(@"Network Available: %@", available ? @"YES" : @"NO");
return available;
}
+ (BOOL)isWiFiConnected {
NetworkStatus status = [self currentNetworkStatus];
BOOL wifi = (status == NetworkStatusReachableViaWiFi);
NSLog(@"WiFi Connected: %@", wifi ? @"YES" : @"NO");
return wifi;
}
+ (BOOL)isCellularConnected {
NetworkStatus status = [self currentNetworkStatus];
BOOL cellular = (status == NetworkStatusReachableViaWWAN);
NSLog(@"Cellular Connected: %@", cellular ? @"YES" : @"NO");
return cellular;
}
@end
// MARK: - 2. Host Reachability Check
@interface HostReachabilityChecker : NSObject
+ (BOOL)isHostReachable:(NSString *)hostName;
+ (void)checkHostReachability:(NSString *)hostName
completion:(void (^)(BOOL reachable))completion;
@end
@implementation HostReachabilityChecker
+ (BOOL)isHostReachable:(NSString *)hostName {
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault,
[hostName UTF8String]);
if (!reachability) {
return NO;
}
SCNetworkReachabilityFlags flags;
BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags);
CFRelease(reachability);
if (!success) {
return NO;
}
BOOL isReachable = (flags & kSCNetworkReachabilityFlagsReachable) != 0;
BOOL needsConnection = (flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0;
BOOL reachable = isReachable && !needsConnection;
NSLog(@"Host '%@' reachable: %@", hostName, reachable ? @"YES" : @"NO");
return reachable;
}
+ (void)checkHostReachability:(NSString *)hostName
completion:(void (^)(BOOL reachable))completion {
// Use NSURLSession to actually check connectivity
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", hostName]];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.timeoutIntervalForRequest = 10.0;
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *task = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
BOOL reachable = (error == nil);
NSLog(@"Host '%@' connectivity check: %@", hostName, reachable ? @"SUCCESS" : @"FAILED");
if (completion) {
completion(reachable);
}
}];
[task resume];
}
@end
// MARK: - 3. Network Connection Type
@interface NetworkConnectionInfo : NSObject
+ (NSString *)getConnectionType;
+ (NSDictionary *)getDetailedNetworkInfo;
@end
@implementation NetworkConnectionInfo
+ (NSString *)getConnectionType {
NetworkStatus status = [NetworkReachability currentNetworkStatus];
NSString *connectionType;
switch (status) {
case NetworkStatusReachableViaWiFi:
connectionType = @"WiFi";
break;
case NetworkStatusReachableViaWWAN:
connectionType = @"Cellular";
break;
default:
connectionType = @"None";
break;
}
NSLog(@"Connection Type: %@", connectionType);
return connectionType;
}
+ (NSDictionary *)getDetailedNetworkInfo {
NSMutableDictionary *info = [NSMutableDictionary dictionary];
// Get network status
NetworkStatus status = [NetworkReachability currentNetworkStatus];
info[@"status"] = @(status);
info[@"statusText"] = [self getConnectionType];
info[@"available"] = @([NetworkReachability isNetworkAvailable]);
info[@"wifi"] = @([NetworkReachability isWiFiConnected]);
info[@"cellular"] = @([NetworkReachability isCellularConnected]);
// Get SSID (WiFi network name) if available
NSString *ssid = [self getCurrentWiFiSSID];
if (ssid) {
info[@"ssid"] = ssid;
}
NSLog(@"Network Info: %@", info);
return [info copy];
}
+ (NSString *)getCurrentWiFiSSID {
CFArrayRef interfaces = CNCopySupportedInterfaces();
if (!interfaces) {
return nil;
}
NSString *ssid = nil;
NSArray *interfaceArray = (__bridge NSArray *)interfaces;
for (NSString *interface in interfaceArray) {
CFDictionaryRef networkInfo = CNCopyCurrentNetworkInfo((__bridge CFStringRef)interface);
if (networkInfo) {
ssid = CFDictionaryGetValue(networkInfo, kCNNetworkInfoKeySSID);
if (ssid) {
ssid = [NSString stringWithString:(__bridge NSString *)ssid];
}
CFRelease(networkInfo);
break;
}
}
CFRelease(interfaces);
if (ssid) {
NSLog(@"WiFi SSID: %@", ssid);
}
return ssid;
}
@end
// MARK: - 4. Network Change Monitor
@interface NetworkMonitor : NSObject
@property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef;
@property (nonatomic, copy) void (^networkChangeBlock)(NetworkStatus status);
- (instancetype)initWithCallback:(void (^)(NetworkStatus status))callback;
- (void)startMonitoring;
- (void)stopMonitoring;
@end
static void NetworkReachabilityCallback(SCNetworkReachabilityRef target,
SCNetworkReachabilityFlags flags,
void *info) {
NetworkMonitor *monitor = (__bridge NetworkMonitor *)info;
BOOL isReachable = (flags & kSCNetworkReachabilityFlagsReachable) != 0;
BOOL needsConnection = (flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0;
BOOL isWWAN = (flags & kSCNetworkReachabilityFlagsIsWWAN) != 0;
NetworkStatus status = NetworkStatusNotReachable;
if (isReachable && !needsConnection) {
status = isWWAN ? NetworkStatusReachableViaWWAN : NetworkStatusReachableViaWiFi;
}
NSLog(@"Network status changed to: %ld", (long)status);
if (monitor.networkChangeBlock) {
monitor.networkChangeBlock(status);
}
}
@implementation NetworkMonitor
- (instancetype)initWithCallback:(void (^)(NetworkStatus status))callback {
self = [super init];
if (self) {
_networkChangeBlock = callback;
}
return self;
}
- (void)startMonitoring {
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
self.reachabilityRef = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault,
(struct sockaddr *)&zeroAddress);
if (self.reachabilityRef) {
SCNetworkReachabilityContext context = {0, (__bridge void *)self, NULL, NULL, NULL};
if (SCNetworkReachabilitySetCallback(self.reachabilityRef,
NetworkReachabilityCallback,
&context)) {
if (SCNetworkReachabilityScheduleWithRunLoop(self.reachabilityRef,
CFRunLoopGetCurrent(),
kCFRunLoopDefaultMode)) {
NSLog(@"Network monitoring started");
}
}
}
}
- (void)stopMonitoring {
if (self.reachabilityRef) {
SCNetworkReachabilityUnscheduleFromRunLoop(self.reachabilityRef,
CFRunLoopGetCurrent(),
kCFRunLoopDefaultMode);
CFRelease(self.reachabilityRef);
self.reachabilityRef = NULL;
NSLog(@"Network monitoring stopped");
}
}
- (void)dealloc {
[self stopMonitoring];
}
@end
// MARK: - 5. Network Speed Test
@interface NetworkSpeedTest : NSObject
+ (void)testDownloadSpeedWithCompletion:(void (^)(double speedMBps))completion;
+ (void)pingHost:(NSString *)host
completion:(void (^)(NSTimeInterval pingTime))completion;
@end
@implementation NetworkSpeedTest
+ (void)testDownloadSpeedWithCompletion:(void (^)(double speedMBps))completion {
NSString *testURLString = @"https://speed.cloudflare.com/__down?bytes=10000000"; // 10MB
NSURL *url = [NSURL URLWithString:testURLString];
NSDate *startTime = [NSDate date];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *task = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Speed test failed: %@", error.localizedDescription);
if (completion) {
completion(0.0);
}
return;
}
NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startTime];
double bytes = data.length;
double mbps = (bytes / 1024 / 1024) / duration;
NSLog(@"Download speed: %.2f MB/s", mbps);
if (completion) {
completion(mbps);
}
}];
[task resume];
}
+ (void)pingHost:(NSString *)host
completion:(void (^)(NSTimeInterval pingTime))completion {
// Use NSURLSession to measure round-trip time
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", host]];
NSDate *startTime = [NSDate date];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.timeoutIntervalForRequest = 5.0;
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask *task = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSTimeInterval pingTime = [[NSDate date] timeIntervalSinceDate:startTime] * 1000; // Convert to ms
if (error) {
NSLog(@"Ping to %@ failed: %@", host, error.localizedDescription);
pingTime = -1;
} else {
NSLog(@"Ping to %@: %.0f ms", host, pingTime);
}
if (completion) {
completion(pingTime);
}
}];
[task resume];
}
@end
// MARK: - Main Demonstration
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"=== macOS Objective-C Network Status Examples ===\n");
// 1. Basic network status
NSLog(@"--- 1. Basic Network Status ---");
BOOL available = [NetworkReachability isNetworkAvailable];
BOOL wifi = [NetworkReachability isWiFiConnected];
BOOL cellular = [NetworkReachability isCellularConnected];
NSLog(@"Network: %@ | WiFi: %@ | Cellular: %@",
available ? @"Available" : @"Unavailable",
wifi ? @"Yes" : @"No",
cellular ? @"Yes" : @"No");
// 2. Connection type
NSLog(@"\n--- 2. Connection Type ---");
NSString *connectionType = [NetworkConnectionInfo getConnectionType];
NSLog(@"Current connection: %@", connectionType);
// 3. Host reachability
NSLog(@"\n--- 3. Host Reachability ---");
NSArray *testHosts = @[@"apple.com", @"google.com", @"github.com", @"localhost"];
for (NSString *host in testHosts) {
[HostReachabilityChecker isHostReachable:host];
}
// 4. Detailed network info
NSLog(@"\n--- 4. Detailed Network Info ---");
NSDictionary *networkInfo = [NetworkConnectionInfo getDetailedNetworkInfo];
NSLog(@"%@", networkInfo);
// 5. Network monitoring setup (demonstration)
NSLog(@"\n--- 5. Network Monitoring Setup ---");
NSLog(@"NetworkMonitor *monitor = [[NetworkMonitor alloc] initWithCallback:^(NetworkStatus status) {");
NSLog(@" NSLog(@\\\"Network changed to: %ld\\\", (long)status);");
NSLog(@"}];");
NSLog(@"[monitor startMonitoring];");
NSLog(@"// Monitor will automatically detect network changes\n");
// 6. Speed test example
NSLog(@"--- 6. Speed Test ---");
NSLog(@"[NetworkSpeedTest testDownloadSpeedWithCompletion:^(double speedMBps) {");
NSLog(@" NSLog(@\\\"Speed: %.2f MB/s\\\", speedMBps);");
NSLog(@"}];\n");
// 7. Ping example
NSLog(@"--- 7. Ping Test ---");
NSLog(@"[NetworkSpeedTest pingHost:@\\\"google.com\\\" completion:^(NSTimeInterval pingTime) {");
NSLog(@" NSLog(@\\\"Ping: %.0f ms\\\", pingTime);");
NSLog(@"}];\n");
NSLog(@"=== Network Status Examples Completed ===");
NSLog(@"\nNote: Some functions like async tests require a run loop");
}
return 0;
}System Feedback
Provide visual and audio feedback using NSHapticFeedback, NSSound, and NSUserNotification
Difficulty
4/10
Estimated time
20 min
Tags
objectivec, macos, feedback
Prerequisites
Objective-C basics, AppKit framework
// macOS Objective-C System Feedback Examples
// Using AppKit and Foundation frameworks
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
// MARK: - 1. System Sound Feedback
@interface SoundFeedback : NSObject
+ (void)playBeep;
+ (void)playSystemSound:(NSString *)soundName;
+ (void)playAlertSound;
+ (void)playErrorSound;
+ (void)playSuccessSound;
@end
@implementation SoundFeedback
+ (void)playBeep {
NSBeep();
NSLog(@"System beep played");
}
+ (void)playSystemSound:(NSString *)soundName {
NSSound *sound = [[NSSound alloc] initWithNamed:soundName];
if (sound) {
[sound play];
NSLog(@"Playing system sound: %@", soundName);
} else {
NSLog(@"Sound not found: %@", soundName);
}
}
+ (void)playAlertSound {
[self playSystemSound:@"Frog"]; // System alert sound
NSLog(@"Alert sound played");
}
+ (void)playErrorSound {
[self playSystemSound:@"Basso"]; // Error sound
NSLog(@"Error sound played");
}
+ (void)playSuccessSound {
[self playSystemSound:@"Glass"]; // Success sound
NSLog(@"Success sound played");
}
@end
// MARK: - 2. Haptic Feedback (macOS 10.11+)
@interface HapticFeedbackHelper : NSObject
+ (void)performGenericFeedback;
+ (void)performAlignmentFeedback;
+ (void)performLevelChangeFeedback;
@end
@implementation HapticFeedbackHelper
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
+ (void)performGenericFeedback {
if (@available(macOS 10.11, *)) {
// Create a haptic feedback pattern
NSHapticFeedbackManager *manager = [NSHapticFeedbackManager defaultPerformer];
NSHapticFeedbackPattern pattern = NSHapticFeedbackPatternGeneric;
[manager performFeedbackPattern:pattern
performanceTime:NSHapticFeedbackPerformanceTimeDefault
error:nil];
NSLog(@"Generic haptic feedback performed");
} else {
NSLog(@"Haptic feedback not available (requires macOS 10.11+)");
}
}
+ (void)performAlignmentFeedback {
if (@available(macOS 10.11, *)) {
NSHapticFeedbackManager *manager = [NSHapticFeedbackManager defaultPerformer];
NSHapticFeedbackPattern pattern = NSHapticFeedbackPatternAlignment;
[manager performFeedbackPattern:pattern
performanceTime:NSHapticFeedbackPerformanceTimeDefault
error:nil];
NSLog(@"Alignment haptic feedback performed");
}
}
+ (void)performLevelChangeFeedback {
if (@available(macOS 10.11, *)) {
NSHapticFeedbackManager *manager = [NSHapticFeedbackManager defaultPerformer];
NSHapticFeedbackPattern pattern = NSHapticFeedbackPatternLevelChange;
[manager performFeedbackPattern:pattern
performanceTime:NSHapticFeedbackPerformanceTimeDefault
error:nil];
NSLog(@"Level change haptic feedback performed");
}
}
#else
+ (void)performGenericFeedback {
NSLog(@"Haptic feedback not available (requires macOS 10.11+)");
}
+ (void)performAlignmentFeedback {
NSLog(@"Haptic feedback not available (requires macOS 10.11+)");
}
+ (void)performLevelChangeFeedback {
NSLog(@"Haptic feedback not available (requires macOS 10.11+)");
}
#endif
@end
// MARK: - 3. Visual Feedback
@interface VisualFeedback : NSObject
+ (void)flashScreen;
+ (void)bounceApplicationIcon;
+ (void)bounceApplicationIconUntilActivated:(BOOL)shouldBounce;
@end
@implementation VisualFeedback
+ (void)flashScreen {
// Flash the screen briefly
[NSAnimationContext beginGrouping];
[NSAnimationContext currentContext].duration = 0.1;
NSWindow *keyWindow = [NSApp keyWindow];
if (keyWindow) {
[NSAnimationContext endGrouping];
NSLog(@"Screen flash performed");
// Alternative: Use notification to alert user
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = @"Attention";
notification.informativeText = @"Flash effect triggered";
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
} else {
NSLog(@"No key window to flash");
}
}
+ (void)bounceApplicationIcon {
NSApplication *app = [NSApplication sharedApplication];
[app requestUserAttention:NSInformationalRequest];
NSLog(@"Application icon bounced once");
}
+ (void)bounceApplicationIconUntilActivated:(BOOL)shouldBounce {
if (shouldBounce) {
[[NSApplication sharedApplication] requestUserAttention:NSCriticalRequest];
NSLog(@"Application icon bouncing until activated");
} else {
[self bounceApplicationIcon];
}
}
@end
// MARK: - 4. Notification Feedback
@interface NotificationFeedback : NSObject
+ (void)showNotification:(NSString *)title
message:(NSString *)message;
+ (void)showNotificationWithSound:(NSString *)title
message:(NSString *)message;
+ (void)showCriticalAlert:(NSString *)title
message:(NSString *)message;
@end
@implementation NotificationFeedback
+ (void)showNotification:(NSString *)title
message:(NSString *)message {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title;
notification.informativeText = message;
notification.soundName = nil; // No sound
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
NSLog(@"Notification shown: %@", title);
}
+ (void)showNotificationWithSound:(NSString *)title
message:(NSString *)message {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title;
notification.informativeText = message;
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
NSLog(@"Notification with sound shown: %@", title);
}
+ (void)showCriticalAlert:(NSString *)title
message:(NSString *)message {
NSUserNotification *notification = [[NSUserNotification alloc] init];
notification.title = title;
notification.informativeText = message;
notification.soundName = NSUserNotificationDefaultSoundName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
// Also bounce the dock icon
[VisualFeedback bounceApplicationIcon];
NSLog(@"Critical alert shown: %@", title);
}
@end
// MARK: - 5. Progress Feedback
@interface ProgressFeedback : NSObject
- (instancetype)initForIndeterminateProgress;
- (void)startProgress;
- (void)stopProgress;
- (void)updateProgress:(double)progress;
@end
@implementation ProgressFeedback
{
NSProgressIndicator *progressIndicator;
NSWindow *progressWindow;
}
- (instancetype)initForIndeterminateProgress {
self = [super init];
if (self) {
// Create progress window
progressWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 400, 100)
styleMask:NSWindowStyleMaskTitled
backing:NSBackingStoreBuffered
defer:NO];
progressWindow.title = @"Progress";
// Create progress indicator
progressIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(50, 40, 300, 20)];
progressIndicator.style = NSProgressIndicatorStyleBar;
progressIndicator.indeterminate = YES;
[progressWindow.contentView addSubview:progressIndicator];
}
return self;
}
- (void)startProgress {
[progressWindow center];
[progressWindow makeKeyAndOrderFront:nil];
[progressIndicator startAnimation:nil];
NSLog(@"Progress started");
}
- (void)stopProgress {
[progressIndicator stopAnimation:nil];
[progressWindow close];
NSLog(@"Progress stopped");
}
- (void)updateProgress:(double)progress {
progressIndicator.indeterminate = NO;
progressIndicator.doubleValue = progress;
NSLog(@"Progress updated: %.0f%%", progress * 100);
}
@end
// MARK: - 6. Combined Feedback Helper
@interface FeedbackHelper : NSObject
+ (void)notifySuccess:(NSString *)message;
+ (void)notifyError:(NSString *)message;
+ (void)notifyWarning:(NSString *)message;
+ (void)notifyWithSound:(NSString *)title
message:(NSString *)message;
@end
@implementation FeedbackHelper
+ (void)notifySuccess:(NSString *)message {
[SoundFeedback playSuccessSound];
[NotificationFeedback showNotification:@"Success" message:message];
NSLog(@"Success feedback: %@", message);
}
+ (void)notifyError:(NSString *)message {
[SoundFeedback playErrorSound];
[NotificationFeedback showCriticalAlert:@"Error" message:message];
[VisualFeedback bounceApplicationIcon];
NSLog(@"Error feedback: %@", message);
}
+ (void)notifyWarning:(NSString *)message {
[SoundFeedback playAlertSound];
[NotificationFeedback showNotification:@"Warning" message:message];
NSLog(@"Warning feedback: %@", message);
}
+ (void)notifyWithSound:(NSString *)title
message:(NSString *)message {
[SoundFeedback playBeep];
[NotificationFeedback showNotificationWithSound:title message:message];
NSLog(@"Notification with sound: %@ - %@", title, message);
}
@end
// MARK: - Main Demonstration
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"=== macOS Objective-C System Feedback Examples ===\n");
// 1. Sound feedback
NSLog(@"--- 1. Sound Feedback ---");
NSLog(@"Playing system sounds...");
[SoundFeedback playBeep];
[NSThread sleepForTimeInterval:0.5];
[SoundFeedback performSelector:@selector(playSuccessSound)
withObject:nil
afterDelay:0.1];
NSLog(@"\nSound feedback methods:");
NSLog(@" - [SoundFeedback playBeep]");
NSLog(@" - [SoundFeedback playAlertSound]");
NSLog(@" - [SoundFeedback playErrorSound]");
NSLog(@" - [SoundFeedback playSuccessSound]\n");
// 2. Haptic feedback
NSLog(@"--- 2. Haptic Feedback ---");
[HapticFeedbackHelper performGenericFeedback];
[NSThread sleepForTimeInterval:0.5];
[HapticFeedbackHelper performAlignmentFeedback];
NSLog(@"\nHaptic feedback methods:");
NSLog(@" - [HapticFeedbackHelper performGenericFeedback]");
NSLog(@" - [HapticFeedbackHelper performAlignmentFeedback]");
NSLog(@" - [HapticFeedbackHelper performLevelChangeFeedback]\n");
// 3. Visual feedback
NSLog(@"--- 3. Visual Feedback ---");
NSLog(@"Bouncing application icon...");
[VisualFeedback bounceApplicationIcon];
NSLog(@"\nVisual feedback methods:");
NSLog(@" - [VisualFeedback flashScreen]");
NSLog(@" - [VisualFeedback bounceApplicationIcon]");
NSLog(@" - [VisualFeedback bounceApplicationIconUntilActivated:YES]\n");
// 4. Notification feedback
NSLog(@"--- 4. Notification Feedback ---");
[NotificationFeedback showNotification:@"Test Notification"
message:@"This is a test notification"];
NSLog(@"\nNotification feedback methods:");
NSLog(@" - [NotificationFeedback showNotification:message:]");
NSLog(@" - [NotificationFeedback showNotificationWithSound:message:]");
NSLog(@" - [NotificationFeedback showCriticalAlert:message:]\n");
// 5. Combined feedback
NSLog(@"--- 5. Combined Feedback Helper ---");
NSLog(@"[FeedbackHelper notifySuccess:@\"Operation completed\\"]");
NSLog(@"[FeedbackHelper notifyError:@\"Operation failed\"]");
NSLog(@"[FeedbackHelper notifyWarning:@\"Low disk space\"]");
NSLog(@"[FeedbackHelper notifyWithSound:@\"Update\" message:@\"New version available\"]\n");
NSLog(@"=== System Feedback Examples Completed ===");
NSLog(@"\nNote: Some feedback types require a GUI application context");
}
return 0;
}Tools
Tools frequently paired with this sample
Related