网易首页 > 网易号 > 正文 申请入驻

AIGC打造Xcode辅助开发插件-iTATools

0
分享至

0.背景

日常的开发迭代中,相信大家都会有很多重复的劳动,略显枯燥和拉低了生产效率。而去年ChatGPT的横空出世,我们有了比谷歌和Github更好的代码咨询小助手。但就像做菜一样,我们首先需要的是准备“环境”来让自己拥有询问小助手的资格,然后打开浏览器,提问-抄答案-commandC-commandV到我们的开发App Xcode 中。用一件枯燥的事情代替了另一件事情。显得非常的不爽,于是便有了直接开发Xcode插件的念头,深度结合AIGC的能力,无缝衔接。iTaTools便因此诞生。

1.成果 1.1 Mac端AIGC小工具

iTaTools首先是一个独立的Mac端的App,这个App的初衷呢其实是组内成员日常学习Swift和SwiftUI的一个辅助App,大家可以使用SwiftUI来构建自己喜欢的功能。首先看一下它的用户界面:


左图为Mac端的iTaTools App,也是主要和AIGC相结合的工具类App,用户可以在第一个Tab中向ChatGPT提问,并等待回答,在第二个Tab中,可以进行文生图的操作,第三个Tab则是汇总了市面上一些AIGC实用的工具和一些使用AIGC的技巧。


1.2 Xcode插件


目前根据平日的需求,制作了四个小插件,分别是

  • 根据所选内容直接生成代码(懂的都懂,它生成的大部分时间比自己写的靠谱)

  • 将后台给的Json假数据直接生成对应的业务模型(可以省去大量的手动书写模型的时间)

  • ‍给相应的代码块或者方法添加苹果官方味道的注释(注释写的好,屎上雕花都不怕)

  • 选中代码块的通俗易懂的解释(程序员最怕的就是看别人的代码,写得再好也需要一个小助手帮忙翻译一下)

这样我们便可以直接在Xcode 开发环境中通过设置自己喜欢的快捷键,直接和ChatGPT交互。下面简单的拿Json2Code举例:第一个图是将这个快捷指令设置快捷键:Command+Shift+Z



给出模型文件的同时,还能够给出Json解析和Demo模型的代码。该插件制作之后的两个月时间,已经有大量业务模型由AIGC产生,节约了大量的时间,而代码生成质量也十分合格,因为不涉及较复杂的业务逻辑,这部分的代码工作交给AIGC是十分合适的。 自动添加注释案例:


1.3 iOS自动生成UI代码

在iTaTools之中,开发者还可以根据自己的需要自动生成UI,按照我们网易新闻iOS团队的开发习惯指定了一个特殊的Prompt,以此来针对性的输出UI代码:

  • 团队使用Objective-C或者Swift语言来搭建用户UI

  • 团队使用第三方框架SnapKit/Masonry来生成自动布局代码

  • 团队代码规范规定使用Get方式生成UI元素,例如文本、图片

  • 团队使用统一的日夜间生成方式以及统一的字号管理方式


开发人员可以通过输入目标文本、图片等基本UI元素的个数、命名,来让App自动生成可以直接使用的代码,下边是生成的代码案例:


根据您的描述,我将为您生成Objective-C的代码:
```Objective-C// NTESNBLoginHeader.h#import
@interface NTESNBLoginHeader : UIView
@property (nonatomic, strong) UILabel *username;@property (nonatomic, strong) UILabel *password;@property (nonatomic, strong) UIImageView *avatar;
- (void)updateUsername:(NSString *)username;- (void)updatePassword:(NSString *)password;- (void)updateAvatar:(UIImage *)avatar;
@end
// NTESNBLoginHeader.m#import "NTESNBLoginHeader.h"#import
@interface NTESNBLoginHeader ()
@end
@implementation NTESNBLoginHeader
- (instancetype)init {self = [super init];if (self) {[self addSubview:self.username];[self addSubview:self.password];[self addSubview:self.avatar];[self setupLayout];return self;
- (UILabel *)username {if (!_username) {_username = [[UILabel alloc] init];_username.textAlignment = NSTextAlignmentCenter;_username.numberOfLines = 0;_username.textColor = [UIColor blackColor];_username.font = [UIFont systemFontOfSize:14];return _username;
- (UILabel *)password {if (!_password) {_password = [[UILabel alloc] init];_password.textAlignment = NSTextAlignmentCenter;_password.numberOfLines = 0;_password.textColor = [UIColor blackColor];_password.font = [UIFont systemFontOfSize:14];return _password;
- (UIImageView *)avatar {if (!_avatar) {_avatar = [[UIImageView alloc] init];_avatar.contentMode = UIViewContentModeCenter;return _avatar;
- (void)setupLayout {// 这里是使用Masonry进行自动布局,请按照您的实际需求进行修改// 示例代码如下:[self.avatar mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self).offset(20);make.centerX.equalTo(self);make.size.mas_equalTo(CGSizeMake(50, 50));[self.username mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self.avatar.mas_bottom).offset(10);make.left.right.equalTo(self);[self.password mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self.username.mas_bottom).offset(10);make.left.right.equalTo(self);
- (void)updateUsername:(NSString *)username {self.username.text = username;
- (void)updatePassword:(NSString *)password {self.password.text = password;
- (void)updateAvatar:(UIImage *)avatar {self.avatar.image = avatar;
@end
2.实现原理 2.1 AIGC API的使用

项目使用的是 ChatGPT官方提供的API,需要注意的是,开发者需要根据自己对接的API提供方来调整API请求,且部分API文档和实现可能已经和实现时存在差异,请以最新文档为准。以下代码均为示例代码。‍‍

2.1.1 请求头

以下是使用Swift语言生成的ChatGPT请求头,关键参数请参考官方文档。


extension NTESNeteaseAIService {/// 创建通用请求Header,授权每次的API请求/// - Parameters:/// - appId: AppID,需要在开发者后台创建/// - appKey: appKey,需要在开发者后台创建/// - Returns: 返回满足条件的Header,时效10分钟,建议每次请求时实时获取当前Headerpublic func signedHeaders(appId: String, appKey: String) -> [String: String] {let nonce = String((0..<10).map{ _ in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".randomElement()! })let timestamp = String(Int64(Date().timeIntervalSince1970))let str2Sign = "appId=\(appId)&nonce=\(nonce)×tamp=\(timestamp)&appkey=\(appKey)"let sign = Insecure.MD5.hash(data: str2Sign.data(using: .utf8)!).map { String(format: "%02hhx", $0) }.joined().uppercased()
var headers = [String: String]()headers["appId"] = appIdheaders["nonce"] = nonceheaders["timestamp"] = timestampheaders["sign"] = signheaders["version"] = "v2"return headers
2.1.2 请求Prompt‍

我们根据API所需要的参数进行用户界面的设计或者Prompt的设计,并拼装请求的参数,这里以json转模型的请求参数为例:


struct message: Decodable, Encodable {let role: String?let content: String?let name: String?let functionCall: functionCall?struct NTESNeteaseAIJson2CodeRequestParams: Encodable {let model: String = "gpt-3.5-turbo"let messages: [NTESNeteaseAIChatResponse.message]//初始化,传入用户输入的描述init(promptString: String) {let finalPrompt = "你现在扮演的是一名资深iOS开发人员 将下面这段Json文件转换成Swift Class 模型文件,注意代码格式,要求类名前缀是NTESNB,并实现init方法,给出一个静态demo变量 \(promptString)"let preparePromptMessage = NTESNeteaseAIChatResponse.message(role: "user", content: finalPrompt,name: "Jerry",functionCall: nil)self.messages = [preparePromptMessage]
2.1.3 解析Response

原理非常的简单,开发者只是将用户的输入组装,将功能转化成Prompt意图传递给ChatGPT,并得到答案解析


struct NTESNeteaseAIChatResponse: Decodable {let status: Stringlet desc: String?let traceId: String?let detail: NTESNeteaseAIChatResponse.detail?
extension NTESNeteaseAIChatResponse {struct detail: Decodable {let id: String?let object: String?let created: TimeInterval?let choices: [NTESNeteaseAIChatResponse.choices]?let usage: NTESNeteaseAIChatResponse.usage?struct choices: Decodable {let index: Int?let finishReason: String?let message: NTESNeteaseAIChatResponse.message?struct message: Decodable, Encodable {let role: String?let content: String?let name: String?let functionCall: functionCall?struct usage: Decodable {let promptTokens: Int?let completionTokens: Int?let totalTokens: Int?struct functionCall: Decodable, Encodable {let name: String?let description: String?let parameters: String?
2.2 Xcode 插件制作

在iOS开发环境Xcode中,同样可以制作属于iOS人自己的插件。iTATools的目标是两个,目前完成了第一个,第二个正在进行中:

  • 通过快捷键,在当前编辑器中插入代码和AIGC内容

  • 通过XPCService生成一个长连的服务,在开发者编写代码时,实时生成代码建议

首先我们聚焦到已经完成的部分,Xcode Source Editor Extension的创建和实现。主要的实现原理和流程大体如下:


  • 创建Mac App的Extension,一个App可以包含各种各样的Extension,比如手表Watch的代码、推送通知的处理代码,这是脱离在主工程之外的App代码,系统可以在脱离主应用的情况下使用我们提供的各种各样的服务。

而在Mac端,我们需要进入系统设置->扩展中,找到并打开需要的插件:


我们便可以在Xcode->Editor最下方看到开启了的插件,随便打开一个代码文件,便可以使用其中的内置功能。

2.2.1 创建Extension

通过File->New->Target 的方式,在macOS中找到Source Editor Extension 并创建。


在整个Extension当中,我们需要关注到如下几个类:

XCSrouceEditorExtension 所有Source Editor必须实现的插件入口,类似主App的应用入口,我们可以在ExtensionDidFinishLaunching中打印Log等。 XCSourceEditorCommand 这个是我们的主战场,上文所说的每一个AIGC功能都是一个Command XCSourceTextBuffer 开发者正在编辑的源文件中的源码信息 XCSourceEditorCommandInvocation 获取源码、操作源码核心类,AIGC内容创作之后借助这个类来改变源码 2.2.2 获取源文件高亮中代码

这一部分代码较长,就不一一贴出来了,只列举部分关键代码。

获取鼠标选中代码块,起始坐标和结束坐标:


let mouseLine = self.buffer.selections.firstObject as? XCSourceTextRangelet mouseLineNum = mouseLine?.start.line ?? 0let mouseColumnNum = mouseLine?.start.column ?? 0let mouseLineEndNum = mouseLine?.end.line ?? 0let mouseColumnEndNum = mouseLine?.end.column ?? 0

将高亮行数的代码拼接:


let startString = String(mouseLineText.dropFirst(mouseColumnNum))var resultString = startStringfor i in mouseLineNum...mouseLineEndNum {let iString = lines[i]if i == mouseLineEndNum {let cutString = String(iString.prefix(mouseColumnEndNum+1))resultString += cutString} else {resultString += iString

最终这部分源码会作为Prompt来传递给ChatGPT。

2.2.3 Json2Code Command

刚才说到每一个AIGC功能都是一个Command,首先创建一个继承自 XCSourceEditorCommand 的类,用户点击Editor中的item或者快捷键呼出功能是,便会走进这个方法:


func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void {}

在这里,直接调用上文创建的NTESNeteaseAIService,发起相应的请求即可,并按照网易杭研接口的Response进行解析即可


guard let (data, response) = try? await URLSession.shared.data(for: request), let httpResponse = response as? HTTPURLResponse else {throw NTESOpenAIError.NTESOpenAIErrorServerErrorif httpResponse.statusCode == 200 {let chatGPTResponse = try self.processChatResponse(data: data)return chatGPTResponse} else {throw NTESOpenAIError.NTESOpenAIErrorMalformedResponse

最后通过invocation类插入得到的Response(记得要调用completionHandler 告诉系统我们正确处理了)


Task {let fileSourceCode = invocation.buffer.completeBufferdo {let suggestion = try await self.openAIService.json2Code(content: fileSourceCode)let messageResult = suggestion.detail?.choices?.firstlet insertedExplanation = "\n\(messageResult?.message?.content ?? "无法生成代码解释,去问你身边的大佬吧, Sorry")\n"invocation.buffer.lines.removeAllObjects()invocation.buffer.lines.add(insertedExplanation)} catch let error {...}completionHandler(nil)
2.2.4 功能菜单栏

想要将刚才创建好的Command的告诉系统,还需要在Extension Info plist文件中配置:


截图中可以看到我们包含了四个Item,四个功能,每一个字典当中配置显示名称、指定类名、指定唯一ID。

3.总结

以ChatGPT为代表的AIGC工具正在逐渐的走进平日的开发工作之中,一些重复性极强的、或者不包含复杂业务逻辑的代码已经完全可以交给AIGC来自动生成,自己则可以专注于核心业务的开发。

而本着别人不管咱们,咱们自己争口红烧肉的态度,Xcode插件结合AIGC则可以实现一些简单的功能,基于XPCService,Xcode还可以做的更多,这一部分需要后续继续的调研和开发。后续可以通过训练子模型(本地)来学习我们的工程代码,来实现更加灵活、更加贴切我们网易新闻团队(可拓展)的开发插件,因为我们团队有着优秀的代码规范,常用且固定的三方库,也有大量自己团队生成的工具库、业务库,这部分是ChatGPT联网都拿不到的。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
连输三场后基德不忍了,赛后点名批评东契奇,他这风格根本赢不了

连输三场后基德不忍了,赛后点名批评东契奇,他这风格根本赢不了

刺头体育
2024-06-13 15:05:14
“环太平洋2024”军演,美国海军为什么要击沉4万吨级准航母?

“环太平洋2024”军演,美国海军为什么要击沉4万吨级准航母?

环球网资讯
2024-06-13 06:36:14
河南一鱼塘发现一条草鱼疑似卡着金镯子,目击者:我拉了十几年鱼了,头一次见!

河南一鱼塘发现一条草鱼疑似卡着金镯子,目击者:我拉了十几年鱼了,头一次见!

潇湘晨报
2024-06-13 20:17:07
《玫瑰的故事》演技评分:朱珠万茜断层差距,刘亦菲8.4分未第一

《玫瑰的故事》演技评分:朱珠万茜断层差距,刘亦菲8.4分未第一

娱乐圈十三太保
2024-06-12 21:31:11
忘掉WTO和自由贸易吧!欧盟宣布对中国电动汽车征收最高48%的关税!

忘掉WTO和自由贸易吧!欧盟宣布对中国电动汽车征收最高48%的关税!

EETOP半导体社区
2024-06-13 11:34:00
2-3、1-3,世界第一之后又一强队倒下,奥运前景堪忧,朱婷也难救

2-3、1-3,世界第一之后又一强队倒下,奥运前景堪忧,朱婷也难救

我就是一个说球的
2024-05-16 21:35:52
普京找到对付美国的计策,中国也要收拾菲律宾,美国日子不好过了

普京找到对付美国的计策,中国也要收拾菲律宾,美国日子不好过了

说天说地说实事
2024-06-11 13:11:12
黄一鸣最终还是怕了,火速删视频!王思聪前女友小羽发声曝真相!

黄一鸣最终还是怕了,火速删视频!王思聪前女友小羽发声曝真相!

花花lo先森
2024-06-13 10:42:27
中国业界申请政府对欧盟乳制品和猪肉展开反补贴反倾销调查?商务部回应

中国业界申请政府对欧盟乳制品和猪肉展开反补贴反倾销调查?商务部回应

财联社
2024-06-13 16:02:15
炒房客全军覆灭,第四城房价从64000元降至52000元,降幅超过20%

炒房客全军覆灭,第四城房价从64000元降至52000元,降幅超过20%

有事问彭叔
2024-06-12 16:58:48
不知几斤几两的哈马斯悲剧了,以色列:生擒哈尼亚,挖出指使者

不知几斤几两的哈马斯悲剧了,以色列:生擒哈尼亚,挖出指使者

娱宙观
2024-05-08 09:17:17
神秘的换妻游戏,背后组织者身份曝光真相令人心痛不已

神秘的换妻游戏,背后组织者身份曝光真相令人心痛不已

小鱼滑
2024-04-20 02:05:06
我担任副镇长8年未获提拔,大学同学来过后,我被提拔为镇长

我担任副镇长8年未获提拔,大学同学来过后,我被提拔为镇长

乔生桂
2024-06-07 11:04:28
国资委公布6户中央企业领导人员任职

国资委公布6户中央企业领导人员任职

界面新闻
2024-06-13 08:11:22
连续27个跌停,27万股民遭“闷杀”,实控人套现20亿离场!证监会出手:这家公司及实控人被立案

连续27个跌停,27万股民遭“闷杀”,实控人套现20亿离场!证监会出手:这家公司及实控人被立案

鲁中晨报
2024-06-13 07:35:05
2024年,正在失控的债务链条,被围猎收割的中产们迎来了终极命运

2024年,正在失控的债务链条,被围猎收割的中产们迎来了终极命运

重远投资观
2024-06-12 11:08:57
越南女生吐槽中国留学生活:女孩化1次妆能用4天,太脏!网友炸锅

越南女生吐槽中国留学生活:女孩化1次妆能用4天,太脏!网友炸锅

番茄说史聊
2024-06-13 20:23:58
凯特全身插满管子的高清照片流出!不露面是因为行动不便,起不来

凯特全身插满管子的高清照片流出!不露面是因为行动不便,起不来

亦纯杂谈
2024-06-13 10:58:45
全乱了!巴西坐拥5大顶级边锋,中锋人才断档:新9号不如里沙利松

全乱了!巴西坐拥5大顶级边锋,中锋人才断档:新9号不如里沙利松

刺头体育
2024-06-13 21:15:33
河南旱灾有多严重?河道干涸,水库见底,323万亩良田绝收。

河南旱灾有多严重?河道干涸,水库见底,323万亩良田绝收。

钱多多多多
2024-06-13 15:25:16
2024-06-14 07:46:44
网易传媒技术团队
网易传媒技术团队
网易新闻技术团队
40文章数 262关注度
往期回顾 全部

科技要闻

小红书员工仅1/5工龄满2年 32岁就不让进了

头条要闻

中专女生爆冷闯进全球数学竞赛12强 超越一众清北学生

头条要闻

中专女生爆冷闯进全球数学竞赛12强 超越一众清北学生

体育要闻

乔丹最想单挑的男人走了

娱乐要闻

森林北报案,称和汪峰的感情遭受压力

财经要闻

私募大佬孙强:中国为什么缺少耐心资本

汽车要闻

升级8155芯片 新款卡罗拉锐放售12.98-18.48万

态度原创

健康
游戏
教育
亲子
房产

晚餐不吃or吃七分饱,哪种更减肥?

火遍全网的“鸣潮公式”,到底是个啥?

教育要闻

安徽新高考志愿怎么填?权威解答来了!——安徽农业大学

亲子要闻

面对成千上万的海外母婴博主,品牌方应该怎么去选?

房产要闻

再度告急!海口连续仨月住宅入市不足千套!竟有楼盘卖爆!

无障碍浏览 进入关怀版