Mobile Development 15 min read

Boost iOS Productivity: Building an AIGC-Powered Xcode Plugin with Swift

This article details how to create iTaTools, a macOS app and Xcode Source Editor Extension that integrates ChatGPT via AIGC to generate code, UI, and documentation directly in Xcode, complete with implementation steps, Swift code samples, and plugin architecture.

NetEase Media Technology Team
NetEase Media Technology Team
NetEase Media Technology Team
Boost iOS Productivity: Building an AIGC-Powered Xcode Plugin with Swift

Background

Repetitive development tasks reduce efficiency. To streamline interaction with ChatGPT, the team built iTaTools , a macOS application and Xcode source‑editor extension that embed AIGC capabilities directly into the development workflow.

Mac AIGC Tool (iTaTools)

iTaTools is a standalone macOS app written in Swift/SwiftUI. It provides three tabs:

ChatGPT query – send prompts and receive text answers.

Text‑to‑image generation.

A curated list of useful AIGC tools and tips.

iTaTools macOS UI
iTaTools macOS UI

Xcode Source Editor Extension

The extension adds four shortcut‑triggered commands that communicate with the ChatGPT API and insert results directly into the editor.

Commands

Generate code from the currently selected text.

Convert JSON mock data into Swift model classes.

Insert Apple‑style documentation comments for the selected code block.

Provide a plain‑language explanation of the selected snippet.

Xcode plugin UI
Xcode plugin UI

Implementation Details

AIGC API Usage

The project uses the official ChatGPT (OpenAI) API. Developers must adapt request headers and payloads to the provider’s documentation.

Request Headers (Swift)

extension NTESNeteaseAIService {
    /// Create signed request headers for the AIGC service
    /// - Parameters: appId and appKey obtained from the developer console
    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()
        return ["appId": appId, "nonce": nonce, "timestamp": timestamp, "sign": sign, "version": "v2"]
    }
}

Prompt Construction

struct NTESNeteaseAIJson2CodeRequestParams: Encodable {
    let model = "gpt-3.5-turbo"
    let messages: [NTESNeteaseAIChatResponse.Message]
    init(promptString: String) {
        let finalPrompt = "You are a senior iOS developer. Convert the following JSON to a Swift class prefixed with NTESNB, include an init method, and provide a static demo variable \(promptString)."
        let message = NTESNeteaseAIChatResponse.Message(role: "user", content: finalPrompt, name: "Jerry", functionCall: nil)
        self.messages = [message]
    }
}

Response Parsing

struct NTESNeteaseAIChatResponse: Decodable {
    let status: String
    let desc: String?
    let traceId: String?
    let detail: Detail?
    struct Detail: Decodable {
        let id: String?
        let object: String?
        let created: TimeInterval?
        let choices: [Choice]?
        let usage: Usage?
    }
    struct Choice: Decodable { let index: Int?; let finishReason: String?; let message: 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? }
}

Xcode Plugin Development

The plugin is built as an Xcode Source Editor Extension . The main development steps are:

Create a new target:

File → New → Target → macOS → Source Editor Extension

.

Implement the required classes:

XCSrouceEditorExtension : Entry point for the extension.

XCSourceEditorCommand : One subclass per AIGC command (e.g., Json2Code, AddComments).

XCSourceTextBuffer : Represents the source file being edited.

XCSourceEditorCommandInvocation : Provides access to the buffer and allows modifications.

Accessing Highlighted Code

let range = self.buffer.selections.firstObject as? XCSourceTextRange
let startLine = range?.start.line ?? 0
let startColumn = range?.start.column ?? 0
let endLine = range?.end.line ?? 0
let endColumn = range?.end.column ?? 0

let startString = String(mouseLineText.dropFirst(startColumn))
var resultString = startString
for i in startLine...endLine {
    let line = lines[i]
    if i == endLine {
        let cut = String(line.prefix(endColumn + 1))
        resultString += cut
    } else {
        resultString += line
    }
}
// resultString is sent as the prompt to ChatGPT

Json2Code Command Implementation

func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: @escaping (Error?) -> Void) {
    let source = invocation.buffer.completeBuffer
    Task {
        do {
            let suggestion = try await self.openAIService.json2Code(content: source)
            let message = suggestion.detail?.choices?.first?.message?.content ?? "Unable to generate code"
            let output = "
\(message)
"
            invocation.buffer.lines.removeAllObjects()
            invocation.buffer.lines.add(output)
            completionHandler(nil)
        } catch {
            completionHandler(error)
        }
    }
}

Info.plist Configuration

The extension’s Info.plist must list each command dictionary with a display name, the implementing class, and a unique identifier. This enables the commands to appear in Xcode’s Editor menu and be bound to shortcuts.

Extension Info.plist
Extension Info.plist

iOS UI Code Generation Example

Using a custom prompt that encodes the team’s UI conventions (Objective‑C/Swift, SnapKit/Masonry layout, Get‑style UI creation, unified dark/light mode), the tool can generate ready‑to‑use UI code. Below is a generated Objective‑C example.

// 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>
@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;
}
- (void)setupLayout {
    [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

Conclusion

Embedding ChatGPT‑based AIGC tools into the IDE eliminates manual copy‑paste cycles and accelerates repetitive, low‑complexity coding tasks. The iTaTools macOS app and Xcode source‑editor extension demonstrate a practical workflow for code generation, model conversion, documentation insertion, and code explanation. Future work may include training local models to better align with team‑specific coding standards and private libraries.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSAutomationpluginChatGPTSwiftXcodeAIGC
NetEase Media Technology Team
Written by

NetEase Media Technology Team

NetEase Media Technology Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.