首页 » 排名链接 » AIGC打造Xcode辅助开发插件-iTATools(代码插件开发生成辅助)

AIGC打造Xcode辅助开发插件-iTATools(代码插件开发生成辅助)

南宫静远 2024-10-29 20:18:20 0

扫一扫用手机浏览

文章目录 [+]

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

1.2 Xcode插件

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

AIGC打造Xcode辅助开发插件-iTATools(代码插件开发生成辅助) 排名链接
(图片来自网络侵删)
根据所选内容直接生成代码(懂的都懂,它生成的大部分时间比自己写的靠谱)将后台给的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 <UIKit/UIKit.h>@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 <Masonry/Masonry.h>@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;}@end2.实现原理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分钟,建议每次请求时实时获取当前Header public 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"] = appId headers["nonce"] = nonce headers["timestamp"] = timestamp headers["sign"] = sign headers["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: String let 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 = startString for 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.NTESOpenAIErrorServerError } if httpResponse.statusCode == 200 { let chatGPTResponse = try self.processChatResponse(data: data) return chatGPTResponse } else { throw NTESOpenAIError.NTESOpenAIErrorMalformedResponse }

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

Task { let fileSourceCode = invocation.buffer.completeBuffer do { let suggestion = try await self.openAIService.json2Code(content: fileSourceCode) let messageResult = suggestion.detail?.choices?.first let 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联网都拿不到的。

作者:刘瑞

来源-微信公众号:网易传媒技术团队

出处:https://mp.weixin.qq.com/s/CHrSQYvyrsPIjyG0YCPLTA

标签:

相关文章

易语言软件,创新编程语言,引领未来发展

随着信息技术的飞速发展,编程语言在各个领域发挥着越来越重要的作用。在我国,易语言作为一种新兴的编程语言,以其独特的优势和便捷性受到...

排名链接 2024-12-31 阅读0 评论0

游戏语言文件,介绍虚拟世界中的沟通艺术

在虚拟世界的大背景下,游戏语言文件作为承载游戏角色对话、系统提示、界面文字等信息的载体,成为了连接玩家与游戏世界的重要桥梁。本文将...

排名链接 2024-12-31 阅读0 评论0