You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

iOS与macOS跨平台应用发布及Objective-C代码复用咨询

跨iOS和macOS应用的发布与Objective-C代码复用方案

刚好之前做过Objective-C的跨平台项目,来分享下我踩过坑后总结的方案,针对你的两个问题逐一解答:

一、如何发布同时支持iOS和macOS的应用

目前有两种主流方案,取决于你的现有项目状态:

1. 基于现有iOS应用用Mac Catalyst快速适配

如果你已经有成熟的iPhone/iPad应用,Mac Catalyst是最快的跨平台路径——它能直接把iOS应用转换成可在macOS上运行的版本:

  • 打开你的iOS项目,在Xcode的「Targets」列表里点击「+」,选择「macOS」分类下的「Mac Catalyst」目标;
  • 配置新目标的Bundle ID、开发者签名(建议和iOS目标用同一套签名,避免后续发布麻烦);
  • 适配macOS特有的交互细节:比如处理鼠标悬停事件、窗口大小自适应、菜单栏功能等,这部分可以通过UIDevice.current.userInterfaceIdiom或者预编译宏TARGET_OS_MAC来区分平台逻辑;
  • 测试无误后,分别打包iOS版本提交到App Store,Mac Catalyst版本提交到Mac App Store(都是通过Archive打包,再用Xcode Organizer提交)。

2. 从零开始创建Multi-platform原生项目

如果是新项目,直接创建Multi-platform项目能获得更原生的跨平台体验:

  • 新建项目时选择「iOS & macOS」的App模板;
  • Xcode会自动生成「Shared」「iOS」「macOS」三个目录,把通用的业务逻辑、工具类放在「Shared」目录,平台特有的UI或功能分别放在对应目录;
  • 发布流程和普通应用一致,分别打包两个平台的版本,提交到各自的应用商店即可。

二、Objective-C项目的代码复用与跨平台自定义按钮

1. 避免重复代码构建Mac应用的方法

核心是共享通用代码+平台条件编译,具体操作:

  • 在项目中新建一个「SharedCode」目录,把通用的模型类、工具类、业务逻辑的.h.m文件放在这里;
  • 添加这些文件时,同时勾选iOS和macOS两个Target(Xcode会自动帮你把文件关联到两个目标);
  • 对于平台特有的代码,用Objective-C的预编译宏做区分,常用宏包括TARGET_OS_IOSTARGET_OS_MAC
    #ifdef TARGET_OS_IOS
        // iOS专属逻辑,比如弹出UIAlertController
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:nil preferredStyle:UIAlertControllerStyleAlert];
        [self presentViewController:alert animated:YES completion:nil];
    #elif TARGET_OS_MAC
        // macOS专属逻辑,比如弹出NSAlert
        NSAlert *alert = [[NSAlert alloc] init];
        [alert setMessageText:@"提示"];
        [alert runModal];
    #endif
    

2. 跨平台自定义按钮的实现

因为iOS用UIButton,macOS用NSButton,我们可以通过宏定义+通用逻辑抽离实现一套代码适配两个平台:

  • 先创建CustomButton.h头文件:
    #import <Foundation/Foundation.h>
    
    // 根据平台定义CustomButton的基类
    #ifdef TARGET_OS_IOS
        #import <UIKit/UIKit.h>
        #define CustomButtonBase UIButton
    #elif TARGET_OS_MAC
        #import <AppKit/AppKit.h>
        #define CustomButtonBase NSButton
    #endif
    
    @interface CustomButton : CustomButtonBase
    
    // 通用方法:设置自定义样式
    - (void)setupCustomStyle;
    
    @end
    
  • 再创建CustomButton.m实现文件:
    #import "CustomButton.h"
    
    @implementation CustomButton
    
    - (void)setupCustomStyle {
        #ifdef TARGET_OS_IOS
            self.backgroundColor = [UIColor systemBlueColor];
            self.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
            [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
            self.layer.cornerRadius = 8.0;
        #elif TARGET_OS_MAC
            self.bezelStyle = NSBezelStyleRounded;
            self.titleFont = [NSFont systemFontOfSize:16 weight:NSFontWeightMedium];
            [self setTitleColor:[NSColor whiteColor] forState:NSControlStateNormal];
            self.backgroundColor = [NSColor systemBlueColor];
            self.wantsLayer = YES;
            self.layer.cornerRadius = 8.0;
        #endif
    }
    
    // 统一初始化方法
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
        if (self) {
            [self setupCustomStyle];
        }
        return self;
    }
    
    // 针对macOS的initWithCoder(如果用Storyboard的话)
    - (instancetype)initWithCoder:(NSCoder *)coder {
        self = [super initWithCoder:coder];
        if (self) {
            [self setupCustomStyle];
        }
        return self;
    }
    
    @end
    
  • 最后把这两个文件添加到iOS和macOS的Target中,在两个平台的代码里就可以直接使用CustomButton,调用setupCustomStyle就能应用统一的自定义样式,平台特有的差异已经在内部处理好了,不用重复写两套代码。

内容的提问来源于stack exchange,提问作者Vulkan

火山引擎 最新活动