前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >iOS开发之如何开发一款Ollama客户端

iOS开发之如何开发一款Ollama客户端

作者头像
YungFan
发布2025-03-18 12:05:18
发布2025-03-18 12:05:18
5400
代码可运行
举报
文章被收录于专栏:学海无涯学海无涯
运行总次数:0
代码可运行

介绍

  • Ollama 是一个开源的本地 AI 模型运行平台,能够在用户的电脑上下载、安装与运行大型语言模型(LLMs)。
  • macOS/iOS 可以调用 Ollama 的客户端很多,如 Cherry Studio、Chatbox、ChatX、Enchanted、NextChat 等。如果想要自己动手开发一款原生 App,可以使用 ollama-swift ,它是一个 Swift 编写的开源库,可以与 Ollama API 进行交互,功能包括管理模型、嵌入、生成、聊天、工具等。

开发步骤

  1. 下载并安装 Ollama。
  2. 通过 Ollama 命令下载并运行大模型。
代码语言:javascript
代码运行次数:0
运行
复制
ollama run 模型名
  1. 设置 Ollama 可以对外提供服务。
代码语言:javascript
代码运行次数:0
运行
复制
launchctl setenv OLLAMA_HOST "0.0.0.0"
launchctl setenv OLLAMA_ORIGINS "*"
  1. 创建 macOS/iOS 项目。
  2. 添加 ollama-swift
  3. 功能开发。

案例

以生成与聊天功能为例。

代码语言:javascript
代码运行次数:0
运行
复制
import Ollama
import SwiftUI

struct ContentView: View {
    @State private var userInput: String = "什么是SwiftUI?"
    @State private var response: String = ""
    @State private var isLoading: Bool = false
    // 默认http://localhost:11434
    let client = Client(host: URL(string: "http://192.168.0.43:11434")!, userAgent: "MyApp/1.0")
    @State private var messages: [Chat.Message] = [.system("你是一个得力的全能助手,可以帮我完成很多任务。")]
    var body: some View {
        VStack(spacing: 16) {
            // 顶部输入区域
            HStack {
                TextField("输入提示词...", text: $userInput)
                    .textFieldStyle(.roundedBorder)
                    .font(.system(size: 16))

                Button {
                    response = ""

                    Task {
                        do {
                            // response = try await generate()
                            // response = try await chatSingleAround()
                            response = try await chatMultipleAround()
                        } catch {
                            debugPrint(error)
                        }
                    }
                } label: {
                    Text("开始")
                        .foregroundStyle(.white)
                        .padding(.horizontal, 16)
                        .padding(.vertical, 8)
                        .background(userInput.isEmpty ? Color.gray : Color.blue)
                        .cornerRadius(8)
                }
                .buttonStyle(.borderless)
                .disabled(userInput.isEmpty || isLoading)
            }
            .padding(.horizontal)
            .padding(.top)

            // 分隔线
            Rectangle()
                .fill(Color.gray.opacity(0.2))
                .frame(height: 1)

            // 响应展示区域
            if response != "" {
                ResponseBubble(text: response)
            }

            Spacer()
        }

        if isLoading {
            ProgressView()
                .progressViewStyle(.circular)
                .padding()
        }
    }

    // 生成
    func generate() async throws -> String {
        isLoading = true
        let response = try await client.generate(
            model: "qwen:0.5b", // 模型
            prompt: userInput,
            stream: false
        )
        isLoading = false
        return response.response
    }

    // 单轮聊天
    func chatSingleAround() async throws -> String {
        isLoading = true
        let response = try await client.chat(
            model: "qwen:0.5b",
            messages: [
                .system("你是一个得力的全能助手,可以帮我完成很多任务。"),
                .user(userInput)
            ]
        )
        isLoading = false
        return response.message.content
    }
    
    // 多轮聊天
    func chatMultipleAround() async throws -> String {
        var response = ""
        isLoading = true
        // 1
        messages.append(.user("什么是SwiftUI?"))
        response.append("1.什么是SwiftUI?\n")
        let response1 = try await client.chat(
            model: "qwen:0.5b",
            messages: messages
        )
        response.append(response1.message.content)
        // 2
        messages.append(.user("SwiftUI和UIKit有什么区别?"))
        response.append("\n\n2.SwiftUI和UIKit有什么区别?\n")
        let response2 = try await client.chat(
            model: "qwen:0.5b",
            messages: messages
        )
        response.append(response2.message.content)
        isLoading = false
        return response
    }
}

struct ResponseBubble: View {
    let text: String

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 8) {
                Text("AI")
                    .font(.system(size: 16))
                    .foregroundColor(.gray)

                Text(text)
                    .font(.system(size: 16))
                    .lineSpacing(4)
                    .padding()
                    .background(Color.blue.opacity(0.1))
                    .cornerRadius(12)
            }
        }
        .padding(.horizontal)
    }
}

效果

  1. 生成。
  1. 单轮聊天。
  1. 多轮聊天。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 开发步骤
  • 案例
  • 效果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档