根据所选内容直接生成代码(懂的都懂,它生成的大部分时间比自己写的靠谱😈)
将后台给的Json假数据直接生成对应的业务模型(可以省去大量的手动书写模型的时间)
给相应的代码块或者方法添加苹果官方味道的注释(注释写的好,屎上雕花都不怕)
选中代码块的通俗易懂的解释(程序员最怕的就是看别人的代码,写得再好也需要一个小助手帮忙翻译一下)
团队使用Objective-C或者Swift语言来搭建用户UI
团队使用第三方框架SnapKit/Masonry来生成自动布局代码
团队代码规范规定使用Get方式生成UI元素,例如文本、图片
团队使用统一的日夜间生成方式以及统一的字号管理方式
开发人员可以通过输入目标文本、图片等基本UI元素的个数、命名,来让App自动生成可以直接使用的代码,下边是生成的代码案例:
根据您的描述,我将为您生成Objective-C的代码:
```Objective-C
// NTESNBLoginHeader.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
@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
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
}
}
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]
}
}
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?
}
}
通过快捷键,在当前编辑器中插入代码和AIGC内容
通过XPCService生成一个长连的服务,在开发者编写代码时,实时生成代码建议
创建Mac App的Extension,一个App可以包含各种各样的Extension,比如手表Watch的代码、推送通知的处理代码,这是脱离在主工程之外的App代码,系统可以在脱离主应用的情况下使用我们提供的各种各样的服务。
在整个Extension当中,我们需要关注到如下几个类:
XCSrouceEditorExtension | 所有Source Editor必须实现的插件入口,类似主App的应用入口,我们可以在ExtensionDidFinishLaunching中打印Log等。 |
XCSourceEditorCommand | 这个是我们的主战场,上文所说的每一个AIGC功能都是一个Command |
XCSourceTextBuffer | 开发者正在编辑的源文件中的源码信息 |
XCSourceEditorCommandInvocation | 获取源码、操作源码核心类,AIGC内容创作之后借助这个类来改变源码 |
这一部分代码较长,就不一一贴出来了,只列举部分关键代码。
获取鼠标选中代码块,起始坐标和结束坐标:
let mouseLine = self.buffer.selections.firstObject as? XCSourceTextRange
let mouseLineNum = mouseLine?.start.line ?? 0
let mouseColumnNum = mouseLine?.start.column ?? 0
let mouseLineEndNum = mouseLine?.end.line ?? 0
let 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。
func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void ) -> Void {}
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
}
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)
}