macOS Objective-C 移动端功能示例
macOS Objective-C 移动端功能示例,包括设备信息、网络状态和系统反馈
💻 设备信息 objectivec
🟢 simple
⭐⭐⭐
使用 NSProcessInfo 和 NSHost 获取设备型号、系统版本和硬件信息
⏱️ 25 min
🏷️ 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 {
kern_return_t kr;
task_info_data_t info;
mach_msg_type_number_t count;
count = TASK_BASIC_INFO_COUNT;
kr = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)info,
&count);
if (kr != KERN_SUCCESS) {
return 0.0;
}
task_basic_info_t basicInfo = (task_basic_info_t)info;
double cpuUsage = basicInfo->cpu_usage / (double)TH_USAGE_SCALE * 100.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;
}
💻 系统反馈 objectivec
🟢 simple
⭐⭐
使用 NSHapticFeedback、NSSound 和 NSUserNotification 提供视觉和音频反馈
⏱️ 20 min
🏷️ 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;
}
💻 网络状态 objectivec
🟡 intermediate
⭐⭐⭐
使用 SCNetworkReachability 和 NSURLSession 检查网络连接状态
⏱️ 30 min
🏷️ 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;
}