iOS开发新手的第一行代码

引言

如果你从来没有接触过iOS开发,你可以看这篇文章,因为这篇文章就是给0基础的小白准备的。

项目结构

一个入门级iOS App的源代码的项目结构大致为以下结构。

css 复制代码
YourProject
    ├── Classes
    │   ├── main.m
    │   ├── AppDelegate.h
    │   ├── AppDelegate.m
    │   ├── SceneDelegate.h
    │   ├── SceneDelegate.m
    │   ├── MainViewController.h
    │   ├── MainViewController.m
    │   ├── MainViewController.storyboard
    │   ├── SecondViewController.h
    │   ├── SecondViewController.m
    │   └── SecondViewController.storyboard
    ├── Info.plist
    └── Assets.xcassets
        ├── AppIcon.appiconset
        ├── MyIcon1.imageset
        └── MyIcon2.imageset

main.m

这是整个iOS App项目的入口。

objc 复制代码
#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char* argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

UIKit 是iOS的基础UI工具包。这里还指定了appDelegateClassName,入口类名为AppDelegate,相当于Android中的Application类。

AppDelegate.h

objc 复制代码
#import <UIKit/UIKit.h>
#import "SceneDelegate.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

    @property (nonatomic, strong) SceneDelegate *scene;

@end

AppDelegate,即App代理,在里面声明了一个SceneDelegate场景代理。

AppDelegate.m

objc 复制代码
#import "AppDelegate.h"
#import "SceneDelegate.h"

@interface AppDelegate()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
    return YES;
}

#pragma mark - UISceneSession lifecycle

- (UISceneConfiguration*)application:(UIApplication*)application configurationForConnectingSceneSession:(UISceneSession*)connectingSceneSession options:(UISceneConnectionOptions*)options {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}

- (void)application:(UIApplication*)application didDiscardSceneSessions:(NSSet<UISceneSession*>*)sceneSessions {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

@end

这里的方法声明最前面的-代表这是一个实例方法,而类方法则为+。实例方法的意思是说,要先创建一个属于这个类的对象,再用指针去指这个方法,即调用这个方法。类方法在Java等语言中又叫静态方法,是不需要创建这个类的对象,直接使用类名即可调用。最前面的()里面的为这个方法的返回值,如(void)表示无返回值,(UISceneConfiguration*)则表示返回的是一个UISceneConfiguration类型的指针。//为单行注释,在它后面的这一行的代码不会参与编译,仅方便程序员阅读和理解代码。

SceneDelegate.h

objc 复制代码
#import <UIKit/UIKit.h>

@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>

    @property (strong, nonatomic) UIWindow *window;

@end

.h文件定义了一个成员属性UIWindow类型的指针,这样可以在.m文件中包含这个头文件SceneDelegate.h,以直接使用window这个属性,而不需要重新定义。

SceneDelegate.m

Storyboard 是一个故事面板,承载着UI布局,后面我们也可以使用nib文件.xib定义UI界面。

objc 复制代码
#import "SceneDelegate.h"
#import "MainViewController.h"

@interface SceneDelegate ()

@end

@implementation SceneDelegate

- (void)scene:(UIScene*)scene willConnectToSession:(UISceneSession*)session options:(UISceneConnectionOptions*)connectionOptions {
    UIWindowScene *windowScene = (UIWindowScene *)scene;
    UIWindow *window = [[UIWindow alloc] initWithWindowScene:windowScene];
    NSLog(@"%@", NSStringFromCGRect(window.bounds));
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainViewController" bundle:nil];
    UIViewController *controller = [storyboard instantiateInitialViewController];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
    [window setRootViewController: navController];
    [window makeKeyAndVisible];
    self.window = window;
}

- (void)sceneDidDisconnect:(UIScene*)scene {
    // Called as the scene is being released by the system.
    // This occurs shortly after the scene enters the background, or when its session is discarded.
    // Release any resources associated with this scene that can be re-created the next time the scene connects.
    // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}

- (void)sceneDidBecomeActive:(UIScene*)scene {
    // Called when the scene has moved from an inactive state to an active state.
    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}

- (void)sceneWillResignActive:(UIScene*)scene {
    // Called when the scene will move from an active state to an inactive state.
    // This may occur due to temporary interruptions (ex. an incoming phone call).
}

- (void)sceneWillEnterForeground:(UIScene*)scene {
    // Called as the scene transitions from the background to the foreground.
    // Use this method to undo the changes made on entering the background.
}

- (void)sceneDidEnterBackground:(UIScene*)scene {
    // Called as the scene transitions from the foreground to the background.
    // Use this method to save data, release shared resources, and store enough scene-specific state information
    // to restore the scene back to its current state.
}

@end

UIWindowScene你可以理解为存放界面的空壳,通过指定一个UIWindow来创建这个对象。UIWindow可以绑定一个根的UIViewController,根的UIViewController又可以有很多子的UIViewController,形成枝和叶 的树状结构。通过控制器UIViewController就可以创建UIStoryboard,也就是我们提到提到的故事面板。

MainViewController.h

objc 复制代码
#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController

@end

这里就不得不提到面向对象 编程了,这个对象不是你谈的那个对象。通过:继承父类UIViewController得到一个子类。你可以理解为抽象的概念具体了一点点,但还不够具体到能确定为一个个体。比如父类是玩具类,我细化概念为奥迪双钻玩具类,不是广告啊。奥迪双钻玩具类又可以细化为陀螺类或悠悠球类。这里赛车类表示不服,我赛车不值得一提吗?你买到的那个具体的陀螺,比如"玄冥寒鲛"就是一个对象。有了类的这个模板,我们可以理解为设计图,就可以创建无数个具体的对象。

MainViewController.m

objc 复制代码
#import "MainViewController.h"
#import "SecondViewController.h"

@interface MainViewController ()

@property (weak, nonatomic) IBOutlet UIButton *btnStart;

@end

@implementation MainViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (IBAction)clickMyFirstButton:(id)sender {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SecondViewController" bundle:nil];
    UIViewController *controller = [storyboard instantiateInitialViewController];
    [self.navigationController pushViewController:controller animated:YES];
}

@end

创建出界面显示了还不过瘾,那么我们可以跳转到另外一个界面。这里就需要用到UIViewController控制器类的对象,这里是一个导航控制器。通过调用它的pushViewController方法,来切换到另外一个界面SecondViewController显示。 由于控制器和界面是一对一绑定的,切换到那个控制器,就相当于切换到那个界面了。IBAction是一个行为类,在故事面板中直接拖拽连线即可绑定这个返回IBAction的方法,故事面板或.xib文件中就可以直接关联某块区域视图View的某种事件,比如点击事件。用户点击那个区域的视图,就会调用这个方法里面的代码,我们这里定义的是发生场景切换。

Info.plist

key-value形式配置一些参数,比如使用宽松的网络策略允许不使用https请求,而使用http请求。

xml 复制代码
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Assets.xcassets

Assets.xcassets目录下存放着项目的图片资源。其中AppIcon.appiconset管理着App在 iPhone、iPad等设备上不同尺寸的App桌面图标。自定义的图片资源也可以放在这个目录下,也可以包括不同分辨率的集合。

扩展函数

NSDictionary+QueryString.h

objc 复制代码
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSDictionary (QueryString)

- (NSString*)queryString;

@end

NS_ASSUME_NONNULL_END

NSDictionaryNSStringNSArrayNSObject 等基础类都来自 Foundation ,它iOS非常重要的基础类库,里面定义了很多基础的功能,我们可以直接调用。在这里我们扩展一个queryString函数。

NSDictionary+QueryString.m

objc 复制代码
#import "NSDictionary+QueryString.h"

@implementation NSDictionary (QueryString)

- (NSString*)queryString {
    NSMutableArray *pairs = [NSMutableArray array];
    [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
        NSString *encodedKey = [key stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        NSString *encodedValue = [value stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
        [pairs addObject:[NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue]];
    }];
    return [pairs componentsJoinedByString:@"&"];
}

@end

self指针指向当前对象,相当于Java语言中的this。这个方法的作用就是将key-value 的字典NSDictionary,相当于Java中的Map,转换成Http中GET请求中带参数拼接的URL。

写到最后

这个是一个简单的iOS App的功能演示的代码的分析,你还需要使用MacBook电脑在AppStore中安装一个名叫XCode 的开发工具以创建一个iOS项目。这个代码是用Objective-C 开发语言写的,用于入门,后续你还可以学习更高级的iOS开发语言Swift来开发iOS App。

相关推荐
用户38034165882977 小时前
视频编辑器的滤镜图内核:Node/Pin 模型怎么设计,撤销重做怎么才不崩
ios
CocoaKier20 小时前
苹果续费成功,几天后付费协议突然失效,导致线上苹果支付全部失败
ios·apple
深念Y1 天前
PVE 安装黑苹果并直通 Quadro P400
macos·ios·黑苹果·驱动·苹果·英伟达·p400
weixin-a153003083161 天前
7.Appium-ios端自动化
ios·appium·自动化
Anhty2 天前
2026九月最新变声器测评:iOS安卓双端适配,低延迟运行更稳定
android·人工智能·功能测试·ios·智能手机
_瑞2 天前
APM_OOMDetector
ios
秋雨梧桐叶落莳2 天前
【iOS】从源码深入理解RunLoop机制
macos·ios·objective-c·cocoa·cocoapods·uikit
烂蜻蜓2 天前
Flask入门教程(二十七):Session Interface API——自定义Session存储后端
网络·ios·flask
用户38034165882972 天前
VideoToolbox 硬编解码的十个坑:为什么它几乎从不报错
ios