Machine Learning Overview

Effortlessly Integrate ChatGPT-4 API on Mac with Xcode: Your Ultimate 2024 Guide to Token-Based Access Without a Monthly Subscription – day 3

openai website with introduction to chatgpt on computer monitor

Introduction: Choosing Between ChatGPT Plus and Token-Based API for SwiftUI Integration

When integrating OpenAI’s ChatGPT into your SwiftUI application, you have two primary options: subscribing to ChatGPT Plus or utilizing the ChatGPT API with token-based pricing. Each approach offers distinct advantages and considerations.

ChatGPT Plus Subscription

ChatGPT Plus is a subscription service priced at $20 per month. Subscribers benefit from:

  • Access to GPT-4: Enhanced language model capabilities.
  • Faster Response Times: Reduced latency during interactions.
  • Priority Access: Uninterrupted service even during peak usage periods.

This subscription is ideal for users seeking a straightforward setup without the need to manage API requests or monitor usage metrics. Learn more

ChatGPT API with Token-Based Pricing

Alternatively, the ChatGPT API operates on a pay-as-you-go model, charging per 1,000 tokens processed. Tokens are segments of text, with 1,000 tokens approximating 750 words. Pricing varies based on the model:

  • GPT-4 Turbo: $0.03 per 1,000 prompt tokens and $0.06 per 1,000 completion tokens.
  • GPT-3.5 Turbo: $0.002 per 1,000 tokens.

This model is advantageous for developers who require flexibility and scalability, allowing for cost control based on actual usage. See API pricing

Key Considerations

  • Cost Efficiency: For high-volume applications, the API’s token-based pricing can be more economical than a fixed monthly subscription.
  • Integration Complexity: Utilizing the API necessitates handling HTTP requests and responses, which may require additional development effort.
  • Feature Access: Some advanced features available to ChatGPT Plus subscribers may not be accessible through the API.

In summary, choosing between ChatGPT Plus and the ChatGPT API depends on your specific needs, usage patterns, and development resources. For seamless integration into a SwiftUI application with controlled costs, the ChatGPT API with token-based pricing is often the preferred choice.





Integrating ChatGPT-4o API in SwiftUI with Xcode


Integrating ChatGPT-4o API in SwiftUI with Xcode

OpenAI’s ChatGPT-4o API enables developers to incorporate advanced language generation capabilities into their applications. This guide demonstrates how to integrate the ChatGPT-4o API into a SwiftUI application using Xcode. Additionally, it emphasizes the importance of setting up payment on the OpenAI platform to avoid common errors.

Prerequisites

  • Xcode installed on your macOS system.
  • Basic understanding of Swift and SwiftUI.
  • An active OpenAI account with API access.

Step 1: Obtain Your OpenAI API Key

  1. Log in to your OpenAI account.
  2. Navigate to the API section.
  3. Generate a new API key and store it securely.

Step 2: Set Up Payment on OpenAI Platform

To prevent errors such as “The model `gpt-4o` does not exist or you do not have access to it,” ensure that your OpenAI account has an active payment method:

  1. Log in to your OpenAI account.
  2. Go to the billing section.
  3. Add a valid payment method.
  4. Review and accept the terms of service.

Setting up payment is crucial to access premium models like ChatGPT-4o.

Step 3: Create the ChatGPTAPI Class in Swift by adding a new file and call it ChatGPTAPI.swift

In your Xcode project, create a new Swift file named ChatGPTAPI.swift and implement the following code:

import Foundation

class ChatGPTAPI {
private let apiKey = "YOUR_API_KEY" // Replace with your OpenAI API key
private let endpoint = "https://api.openai.com/v1/chat/completions"

func sendMessage(_ message: String, completion: @escaping (String?) -> Void) {
guard let url = URL(string: endpoint) else {
print("Invalid URL")
completion(nil)
return
}

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")

let parameters: [String: Any] = [
"model": "gpt-4o",  // Use "gpt-4o-mini" if needed for lower cost
"messages": [
["role": "system", "content": "You are a helpful assistant."],
["role": "user", "content": message]
],
"temperature": 0.7
]

request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)

URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Network error: \(error.localizedDescription)")
completion("Network error: \(error.localizedDescription)")
return
}

guard let data = data else {
print("No data received")
completion("No data received")
return
}

if let jsonString = String(data: data, encoding: .utf8) {
print("Raw JSON response: \(jsonString)")
}

do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any],
let choices = json["choices"] as? [[String: Any]],
let message = choices.first?["message"] as? [String: Any],
let content = message["content"] as? String {
completion(content)
} else {
print("Unexpected JSON structure")
completion("Failed to parse response JSON")
}
} catch {
print("JSON parsing error: \(error.localizedDescription)")
completion("JSON parsing error: \(error.localizedDescription)")
}
}.resume()
}
}

Step 4: Develop the SwiftUI Interface

In your SwiftUI view, integrate the ChatGPTAPI class to handle user input and display the AI’s response:

import SwiftUI

struct ContentView: View {
@State private var userInput: String = ""
@State private var chatResponse: String = "Awaiting response..."
private let chatGPTAPI = ChatGPTAPI()

var body: some View {
VStack {
Text("ChatGPT")
.font(.largeTitle)
.padding()

TextField("Enter a message", text: $userInput)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()

Button(action: {
chatGPTAPI.sendMessage(userInput) { response in
DispatchQueue.main.async {
chatResponse = response ?? "No response received."
}
}
}) {
Text("Send")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
.padding()

Text("Response:")
.font(.headline)
.padding(.top)

Text(chatResponse)
.padding()
.border(Color.gray, width: 1)
}
.padding()
}
}

Additional Explanation of Integration Choices

Here’s a detailed explanation of the different integration options we considered, the packages involved, and why we ultimately chose a direct approach for implementing the ChatGPT API.

Overview of Implementation

When integrating OpenAI’s ChatGPT API into an iOS app, we evaluated a few approaches:

  1. Using Third-Party Networking Packages (like Alamofire)
  2. Using OpenAI-Specific Swift Packages
  3. Direct Integration with OpenAI’s API via URLSession

Each option has its pros and cons. Here’s a breakdown of each:

Option 1: Using Networking Packages like Alamofire

About Alamofire:
Alamofire is a popular networking library for Swift, known for simplifying HTTP requests by abstracting the complexities of URLSession.

  • Why Considered: Alamofire can make network calls easier, particularly for handling JSON APIs like OpenAI’s, by providing convenient methods for request handling.
  • Why We Didn’t Choose It: Adding Alamofire introduces dependency overhead. Since our API calls are straightforward, Alamofire’s features added limited value. Plus, Swift’s URLSession has evolved to be quite capable for our needs.

Option 2: OpenAI-Specific Swift Packages

About OpenAI Swift Packages:
Some third-party developers have created libraries specifically for OpenAI’s API, like OpenAISwift or SwiftOpenAI. These libraries encapsulate the details of API calls, making it easier to work with OpenAI models.

  • Why Considered: OpenAI-specific packages can simplify API integration, especially for developers wanting minimal configuration.
  • Why We Didn’t Choose It: Using third-party libraries can introduce maintenance and compatibility risks if the library is not updated. Direct use of URLSession aligns with OpenAI’s documentation, and we can respond to changes directly without waiting for third-party updates.

Option 3: Direct Integration with URLSession (Chosen Approach)

Using URLSession:
URLSession is a built-in networking API in Swift, providing asynchronous handling of requests and responses, error management, and complete customization of headers and body content.

  • Why We Chose This Approach: URLSession gives us direct control, aligns with OpenAI documentation, and reduces dependencies, keeping the project lightweight and future-proof.

What’s New in 2024 for OpenAI Integration

OpenAI’s API has introduced a few updates:

  • Expanded Model Options: New models like gpt-4-turbo offer optimized performance at different cost levels.
  • Project-Specific API Keys: OpenAI now encourages using project-scoped API keys, which are more secure than user-wide keys.
  • Payment Requirements: Access to premium models often requires an active payment setup.

Summary of Our Approach and Final Choice

We opted for a direct API integration using URLSession because it provides:

  • Full Control: Complete flexibility over requests and responses, directly following OpenAI’s official documentation.
  • Minimal Dependencies: Avoids third-party packages, reducing project complexity and potential maintenance issues.
  • Future-Proofing: Direct integration keeps our project adaptable to OpenAI’s API updates without relying on library support.

Lets now Finalizing Our ChatGPT Integration code with Improved UI

In this final part, we enhance our ChatGPT interface with added functionality for a better user experience. This includes adding a loading indicator, enabling scrollable and copyable responses, and making the app compatible with both iOS and macOS platforms.

Code Implementation

Below is the complete SwiftUI code with improvements. These improvements ensure that users can see when ChatGPT is “thinking,” and also enable them to copy responses from the app. This approach provides a smooth user experience, similar to the official ChatGPT interface. so we suggest change the contentview file to this one instead

import SwiftUI

struct ContentView: View {
    @State private var userInput: String = ""
    @State private var chatResponse: String = "Awaiting response..."
    @State private var isLoading: Bool = false // Loading indicator
    private let chatGPTAPI = ChatGPTAPI()

    var body: some View {
        VStack {
            Text("ChatGPT")
                .font(.largeTitle)
                .padding()

            #if os(iOS)
            TextField("Enter a message", text: $userInput)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            #elseif os(macOS)
            TextField("Enter a message", text: $userInput)
                .textFieldStyle(PlainTextFieldStyle())
                .padding(.horizontal, 20)
                .padding(.vertical, 8)
            #endif

            Button(action: {
                isLoading = true // Start loading
                chatGPTAPI.sendMessage(userInput) { response in
                    DispatchQueue.main.async {
                        chatResponse = response ?? "No response received."
                        isLoading = false // Stop loading once response is received
                    }
                }
            }) {
                Text("Send")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }
            .padding()

            Text("Response:")
                .font(.headline)
                .padding(.top)

            if isLoading {
                ProgressView("Thinking...") // Loading indicator with text
                    .padding()
            } else {
                // Scrollable and copyable response text
                ScrollView {
                    Text(chatResponse)
                        .padding()
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .background(Color(UIColor.systemGray6)) // Light gray background like ChatGPT
                        .cornerRadius(12) // Rounded corners
                        .overlay(
                            RoundedRectangle(cornerRadius: 12)
                                .stroke(Color.gray.opacity(0.3), lineWidth: 1) // Border for ChatGPT style
                        )
                        .font(.system(size: 16, weight: .medium)) // Font styling
                        .foregroundColor(.primary) // Text color
                        .textSelection(.enabled) // Enables copying
                }
                .frame(maxHeight: 300) // Scrollable height limit
                .padding(.horizontal) // Padding for cleaner look
            }
        }
        .padding()
    }
}

Explanation of Improvements

  • Loading Indicator: We added a loading indicator using ProgressView("Thinking...") to show when the app is processing the user’s request. This visual feedback helps users know the app is working.
  • Cross-Platform Compatibility: Using #if os(iOS) and #elseif os(macOS) directives, the app now works seamlessly on both iOS and macOS devices. This means you can run the app on your iPhone, iPad, or Mac with the same codebase.
  • Scrollable and Copyable Responses: The response text is now wrapped in a ScrollView, making it scrollable for longer responses. Additionally, .textSelection(.enabled) allows users to select and copy the response text, similar to the official ChatGPT interface.
  • ChatGPT-Like Styling: We added a light gray background with rounded corners and a subtle border around the response text to mimic the ChatGPT style. This creates a familiar and user-friendly look and feel.

This enhanced version improves the usability and appearance of our ChatGPT app, making it more practical and polished for end-users.