文章的目的为了记录使用Objective-C 进行IOS app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
开源 Objective-C IOS 应用开发(一)macOS 的使用
开源 Objective-C IOS 应用开发(二)Xcode安装
开源 Objective-C IOS 应用开发(三)第一个iPhone的APP
开源 Objective-C IOS 应用开发(四)Xcode工程文件结构
开源 Objective-C IOS 应用开发(五)iOS操作(action)和输出口(Outlet)
推荐链接:
开源 Arkts 鸿蒙应用 开发(一)工程文件分析-CSDN博客
开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用-CSDN博客
开源 Arkts 鸿蒙应用 开发(三)Arkts的介绍-CSDN博客
开源 Arkts 鸿蒙应用 开发(四)布局和常用控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(六)数据持久--文件和首选项存储-CSDN博客
开源 Arkts 鸿蒙应用 开发(七)数据持久--sqlite关系数据库-CSDN博客
开源 Arkts 鸿蒙应用 开发(八)多媒体--相册和相机-CSDN博客
开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端-CSDN博客
开源 Arkts 鸿蒙应用 开发(十)通讯--Http-CSDN博客
开源 Arkts 鸿蒙应用 开发(十一)证书和包名修改-CSDN博客
开源 Arkts 鸿蒙应用 开发(十二)传感器的使用-CSDN博客
开源 Arkts 鸿蒙应用 开发(十三)音频--MP3播放_arkts avplayer播放音频 mp3-CSDN博客
开源 Arkts 鸿蒙应用 开发(十四)线程--任务池(taskpool)-CSDN博客
开源 Arkts 鸿蒙应用 开发(十五)自定义绘图控件--仪表盘-CSDN博客
开源 Arkts 鸿蒙应用 开发(十六)自定义绘图控件--波形图-CSDN博客
开源 Arkts 鸿蒙应用 开发(十七)通讯--http多文件下载-CSDN博客
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器-CSDN博客
推荐链接:
开源 java android app 开发(一)开发环境的搭建-CSDN博客
开源 java android app 开发(二)工程文件结构-CSDN博客
开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客
开源 java android app 开发(四)GUI界面重要组件-CSDN博客
开源 java android app 开发(五)文件和数据库存储-CSDN博客
开源 java android app 开发(六)多媒体使用-CSDN博客
开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客
开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客
开源 java android app 开发(九)后台之线程和服务-CSDN博客
开源 java android app 开发(十)广播机制-CSDN博客
开源 java android app 开发(十一)调试、发布-CSDN博客
开源 java android app 开发(十二)封库.aar-CSDN博客
本章内容主要演示iphone传感器的数据读取,读取陀螺仪和gps的数据。
目录:
1.手机演示
2.所有源码
3.源码分析
一、手机演示

二、所有源码
AppDelegate.h文件
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
AppDelegate.m文件
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 创建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 创建ViewController
ViewController *viewController = [[ViewController alloc] init];
// 设置根视图控制器
self.window.rootViewController = viewController;
// 显示窗口
[self.window makeKeyAndVisible];
return YES;
}
@end
ViewController.h文件
#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
#import <CoreLocation/CoreLocation.h>
@interface ViewController : UIViewController <CLLocationManagerDelegate>
@property (strong, nonatomic) UITextField *gyroTextField;
@property (strong, nonatomic) UITextField *gpsTextField;
@property (strong, nonatomic) UIButton *sensorButton;
// 运动管理器
@property (strong, nonatomic) CMMotionManager *motionManager;
// 位置管理器
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
ViewController.m文件
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
[self setupSensors];
}
- (void)setupUI {
self.view.backgroundColor = [UIColor whiteColor];
// 获取屏幕尺寸
CGRect screenBounds = [UIScreen mainScreen].bounds;
CGFloat screenWidth = screenBounds.size.width;
// 陀螺仪文本框
self.gyroTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, screenWidth - 40, 40)];
self.gyroTextField.placeholder = @"陀螺仪数据将显示在这里";
self.gyroTextField.borderStyle = UITextBorderStyleRoundedRect;
self.gyroTextField.enabled = NO;
self.gyroTextField.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.gyroTextField];
// GPS文本框
self.gpsTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 160, screenWidth - 40, 40)];
self.gpsTextField.placeholder = @"GPS数据将显示在这里";
self.gpsTextField.borderStyle = UITextBorderStyleRoundedRect;
self.gpsTextField.enabled = NO;
self.gpsTextField.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.gpsTextField];
// 传感器按钮
self.sensorButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.sensorButton.frame = CGRectMake(20, 220, screenWidth - 40, 44);
[self.sensorButton setTitle:@"开始读取传感器数据" forState:UIControlStateNormal];
[self.sensorButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
self.sensorButton.backgroundColor = [UIColor systemBlueColor];
self.sensorButton.layer.cornerRadius = 8;
[self.sensorButton addTarget:self action:@selector(toggleSensorReading) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.sensorButton];
// 添加标题标签
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 60, screenWidth - 40, 30)];
titleLabel.text = @"传感器数据读取";
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.font = [UIFont boldSystemFontOfSize:18];
[self.view addSubview:titleLabel];
}
- (void)setupSensors {
// 初始化运动管理器
self.motionManager = [[CMMotionManager alloc] init];
// 初始化位置管理器
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
- (void)toggleSensorReading {
if ([self.sensorButton.titleLabel.text isEqualToString:@"开始读取传感器数据"]) {
[self startSensorReading];
[self.sensorButton setTitle:@"停止读取传感器数据" forState:UIControlStateNormal];
} else {
[self stopSensorReading];
[self.sensorButton setTitle:@"开始读取传感器数据" forState:UIControlStateNormal];
}
}
- (void)startSensorReading {
// 开始陀螺仪数据读取
if (self.motionManager.isGyroAvailable) {
self.motionManager.gyroUpdateInterval = 0.1; // 更新频率10Hz
[self.motionManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMGyroData * _Nullable gyroData, NSError * _Nullable error) {
if (error) {
self.gyroTextField.text = [NSString stringWithFormat:@"陀螺仪错误: %@", error.localizedDescription];
return;
}
if (gyroData) {
NSString *gyroText = [NSString stringWithFormat:@"X: %.4f, Y: %.4f, Z: %.4f",
gyroData.rotationRate.x,
gyroData.rotationRate.y,
gyroData.rotationRate.z];
self.gyroTextField.text = gyroText;
}
}];
} else {
self.gyroTextField.text = @"陀螺仪不可用";
}
// 请求位置权限并开始GPS更新
if ([CLLocationManager locationServicesEnabled]) {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestWhenInUseAuthorization];
} else if (status == kCLAuthorizationStatusAuthorizedWhenInUse ||
status == kCLAuthorizationStatusAuthorizedAlways) {
[self.locationManager startUpdatingLocation];
} else {
self.gpsTextField.text = @"位置服务未授权";
}
} else {
self.gpsTextField.text = @"位置服务不可用";
}
}
- (void)stopSensorReading {
// 停止陀螺仪更新
if (self.motionManager.isGyroActive) {
[self.motionManager stopGyroUpdates];
}
// 停止位置更新
[self.locationManager stopUpdatingLocation];
self.gyroTextField.text = @"已停止";
self.gpsTextField.text = @"已停止";
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *currentLocation = [locations lastObject];
NSString *gpsText = [NSString stringWithFormat:@"经度: %.6f, 纬度: %.6f",
currentLocation.coordinate.longitude,
currentLocation.coordinate.latitude];
self.gpsTextField.text = gpsText;
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
self.gpsTextField.text = [NSString stringWithFormat:@"GPS错误: %@", error.localizedDescription];
}
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
CLAuthorizationStatus status = manager.authorizationStatus;
if (status == kCLAuthorizationStatusAuthorizedWhenInUse ||
status == kCLAuthorizationStatusAuthorizedAlways) {
[self.locationManager startUpdatingLocation];
} else if (status == kCLAuthorizationStatusDenied) {
self.gpsTextField.text = @"位置服务被拒绝";
}
}
- (void)dealloc {
[self stopSensorReading];
}
@end
info.plist文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要您的位置权限来显示GPS数据</string>
</dict>
</plist>
三、源码分析
AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
-
功能:声明AppDelegate类,继承UIResponder,遵循UIApplicationDelegate协议
-
关键属性 :
UIWindow *window- 应用的主窗口
AppDelegate.m
application:didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 创建窗口 - 使用屏幕边界初始化窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 创建ViewController - 初始化主视图控制器
ViewController *viewController = [[ViewController alloc] init];
// 设置根视图控制器 - 将ViewController设置为窗口的根控制器
self.window.rootViewController = viewController;
// 显示窗口 - 使窗口可见并设置为关键窗口
[self.window makeKeyAndVisible];
return YES;
}
作用:应用启动入口点,完成窗口和界面初始化
ViewController.h
@interface ViewController : UIViewController <CLLocationManagerDelegate>
// UI控件属性
@property (strong, nonatomic) UITextField *gyroTextField;
@property (strong, nonatomic) UITextField *gpsTextField;
@property (strong, nonatomic) UIButton *sensorButton;
// 传感器管理器
@property (strong, nonatomic) CMMotionManager *motionManager;
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
功能:声明视图控制器类,遵循CLLocationManagerDelegate协议,定义所有UI和传感器相关属性
ViewController.m
viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI]; // 初始化用户界面
[self setupSensors]; // 初始化传感器
}
作用:视图控制器加载完成后调用,进行界面和传感器的初始化
setupUI
- (void)setupUI {
// 设置背景色
self.view.backgroundColor = [UIColor whiteColor];
// 获取屏幕尺寸
CGRect screenBounds = [UIScreen mainScreen].bounds;
CGFloat screenWidth = screenBounds.size.width;
// 创建并配置陀螺仪文本框
self.gyroTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 100, screenWidth - 40, 40)];
// ... 文本框属性设置
[self.view addSubview:self.gyroTextField];
// 创建并配置GPS文本框
self.gpsTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 160, screenWidth - 40, 40)];
// ... 文本框属性设置
[self.view addSubview:self.gpsTextField];
// 创建并配置传感器按钮
self.sensorButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.sensorButton.frame = CGRectMake(20, 220, screenWidth - 40, 44);
// ... 按钮属性设置
[self.sensorButton addTarget:self action:@selector(toggleSensorReading) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.sensorButton];
// 创建并配置标题标签
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 60, screenWidth - 40, 30)];
// ... 标签属性设置
[self.view addSubview:titleLabel];
}
作用:创建所有UI控件并设置它们的布局和属性
setupSensors
- (void)setupSensors {
// 初始化运动管理器 - 用于访问陀螺仪等运动数据
self.motionManager = [[CMMotionManager alloc] init];
// 初始化位置管理器 - 用于访问GPS位置数据
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; // 设置代理
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置定位精度
}
作用:初始化传感器管理器对象
toggleSensorReading
- (void)toggleSensorReading {
if ([self.sensorButton.titleLabel.text isEqualToString:@"开始读取传感器数据"]) {
[self startSensorReading]; // 开始读取
[self.sensorButton setTitle:@"停止读取传感器数据" forState:UIControlStateNormal];
} else {
[self stopSensorReading]; // 停止读取
[self.sensorButton setTitle:@"开始读取传感器数据" forState:UIControlStateNormal];
}
}
作用:按钮点击事件处理,切换传感器读取状态
startSensorReading
- (void)startSensorReading {
// 陀螺仪部分
if (self.motionManager.isGyroAvailable) {
self.motionManager.gyroUpdateInterval = 0.1; // 设置更新频率为10Hz
// 开始陀螺仪更新,使用主队列接收数据
[self.motionManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue]
withHandler:^(CMGyroData *gyroData, NSError *error) {
// 处理陀螺仪数据或错误
}];
}
// GPS部分
if ([CLLocationManager locationServicesEnabled]) {
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
// 根据权限状态处理
if (status == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestWhenInUseAuthorization]; // 请求权限
} else if (有权限) {
[self.locationManager startUpdatingLocation]; // 开始定位
}
}
}
作用:启动所有传感器数据读取
stopSensorReading
- (void)stopSensorReading {
// 停止陀螺仪更新
if (self.motionManager.isGyroActive) {
[self.motionManager stopGyroUpdates];
}
// 停止位置更新
[self.locationManager stopUpdatingLocation];
// 更新UI显示
self.gyroTextField.text = @"已停止";
self.gpsTextField.text = @"已停止";
}
作用:停止所有传感器数据读取
CLLocationManagerDelegate 方法
locationManager:didUpdateLocations:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *currentLocation = [locations lastObject]; // 获取最新位置
// 格式化并显示经纬度信息
NSString *gpsText = [NSString stringWithFormat:@"经度: %.6f, 纬度: %.6f",
currentLocation.coordinate.longitude,
currentLocation.coordinate.latitude];
self.gpsTextField.text = gpsText;
}
作用:位置更新时调用,显示新的GPS坐标
locationManager:didFailWithError:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
self.gpsTextField.text = [NSString stringWithFormat:@"GPS错误: %@", error.localizedDescription];
}
作用:定位失败时调用,显示错误信息
locationManagerDidChangeAuthorization:
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
CLAuthorizationStatus status = manager.authorizationStatus;
// 权限状态变化时处理
if (有权限) {
[self.locationManager startUpdatingLocation]; // 开始定位
} else if (被拒绝) {
self.gpsTextField.text = @"位置服务被拒绝"; // 显示拒绝信息
}
}
作用:位置权限状态变化时调用
dealloc
- (void)dealloc {
[self stopSensorReading]; // 停止所有传感器读取
}
作用:对象销毁时调用,清理资源
代码执行流程:
-
启动 →
application:didFinishLaunchingWithOptions: -
界面加载 →
viewDidLoad→setupUI+setupSensors -
用户交互 →
toggleSensorReading→startSensorReading/stopSensorReading -
数据更新 → 陀螺仪handler / 位置代理方法更新UI
-
权限处理 →
locationManagerDidChangeAuthorization:处理权限状态变化