5 |
6 | 
7 | [](https://img.shields.io/badge/Swift%20Compatibility-5.5%20%7C%205.6%20%7C%205.7-orange)
8 | [](https://img.shields.io/badge/Platform%20Compatibility-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS-blue)
9 | [](https://img.shields.io/badge/%20licence-MIT-green)
10 |
11 | OpenAI is a community-maintained repository containing Swift implementation over [OpenAI public API](https://platform.openai.com/docs/api-reference/).
12 |
13 | - [Overview](#overview)
14 | - [Installation](#installation)
15 | - [CocoaPods](#cocoapods)
16 | - [Swift Package Manager](#swift-package-manager)
17 | - [Usage](#usage)
18 | - [Initialization](#initialization)
19 | - [Additional Initialization parameters](#additional-initialization-parameters)
20 | - [SSL Handshake](#ssl-handshake)
21 | - [What is this and why you may use it?](#what-is-this-and-why-you-may-use-it)
22 | - [The advantages of this solution](#the-advantages-of-this-solution)
23 | - [How to use SSL Handshake](#how-to-use-ssl-handshake)
24 | - [Completions](#completions)
25 | - [Completions](#completions)
26 | - [Chat Completions](#chat-completions)
27 | - [Stream](#stream)
28 | - [JSON mode](#json-mode)
29 | - [Generate Image](#generate-image)
30 | - [Contribute](#contribute)
31 | - [License](#license)
32 |
33 | ## Overview
34 | The OpenAI API can be applied to virtually any task that involves understanding or generating natural language or code. We offer a spectrum of models with different levels of power suitable for different tasks, as well as the ability to fine-tune your own custom models. These models can be used for everything from content generation to semantic search and classification.
35 |
36 | ## Installation
37 |
38 | OpenAI is available with CocoaPods and Swift Package Manager.
39 |
40 | ### CocoaPods
41 |
42 | [CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate OpenAI into your Xcode project using CocoaPods, specify it in your `Podfile`:
43 |
44 | ```ruby
45 | pod 'OpenAIKit'
46 | ```
47 | ### Swift Package Manager
48 |
49 | The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler.
50 |
51 | Once you have your Swift package set up, adding OpenAI as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.
52 |
53 | ```swift
54 | dependencies: [
55 | .package(url: "https://github.com/FuturraGroup/OpenAI.git", .branch("main"))
56 | ]
57 | ```
58 |
59 | ## Usage
60 |
61 | ### Initialization
62 |
63 | It is encouraged to use environment variables to inject the [OpenAI API key](https://platform.openai.com/account/api-keys), instead of hardcoding it in the source code. This is shown in our [Example project](https://github.com/FuturraGroup/OpenAI/tree/main/Example).
64 |
65 | ```swift
66 | let apiToken: String = ""
67 | let organizationName: String = ""
68 | ```
69 | Initialize `OpenAIKit` with your API Token wherever convenient in your project. Organization name is optional.
70 |
71 | ```swift
72 | import OpenAIKit
73 |
74 | public let openAI = OpenAIKit(apiToken: apiToken, organization: organizationName)
75 | ```
76 |
77 | #### Additional Initialization parameters
78 | Additional optional initializations parameters list:
79 |
80 | - `timeoutInterval: TimeInterval` - timeout interval for OpenAI API response. Default value is `60` sec.
81 | - `customOpenAIURL: String?` - custom endpoint to customize OpenAI API endpoint. Default value is `nil`. **Attention!** If you customize `customOpenAIURL` with your own instead of default OpenAI URL (for example `customOpenAIURL: "https://openai.mysite.test"`) - routes and method **DOESN'T CHANGE**! All routes keep their implementation from [OpenAI public API](https://platform.openai.com/docs/api-reference/).
82 | - `sslCerificatePath: String?` - path to `*.cer` SSL certificate file to validate it with OpenAI's certificate or your server's if you use custom `customOpenAIURL`. Default value is `nil`.
83 |
84 | ### SSL Handshake
85 |
86 | As described in the [Additional Initialization parameters](#additional-initialization-parameters) section, we accept an additional parameter `sslCerificatePath` to establish an SSL handshake with OpenAI or your own server.
87 |
88 | #### What is this and why you may use it?
89 |
90 | First of all - we made this feature to protect from MITM attack. We verify certificate from provided path `sslCerificatePath` with SSL certificate from OpenAI's or your server. If certificates doesn't match we canceling this request.
91 |
92 | #### The advantages of this solution
93 |
94 | - Protecting your data from MITM attack. If someone in network where launches your app executing MITM attack - Your [OpenAI API key](https://platform.openai.com/account/api-keys) in safe. They can't access any private data from request and they'll get error about `SSL Handshake Failure`.
95 | - Don't waste your tokens for hackers. After cancelling request with `SSL Handshake Failure` request doesn't execute and doesn't send any data to OpenAI and you don't waste your request tokens on them!
96 | - You can use this feature with your server, just provide you SSL certificate instead of OpenAI's.
97 |
98 | #### How to use SSL Handshake
99 |
100 | **Attention! We _DON'T SAVE_ any certificates and _DOESN'T MANAGE_ them!
101 | We use the data from the provided `*.cer` file _ONLY_ for comparison with the server certificate.
102 | We are _not responsible_ for the relevance and integrity of the provided certificate.**
103 |
104 | **These actions are within the competence of our library, and you yourself must monitor the validity of the certificate, be responsible for downloading new versions, etc.**
105 |
106 |
107 | **The procedure described below is an instruction on how to correctly obtain an open OpenAI SSL certificate. We are not responsible for any changes to this certificate and its loss of relevance after you have received it.**
108 |
109 | **How to use SSL Handshake:**
110 |
111 | 1. Get SSL Certificate from OpenAI
112 | - Open `https://api.openai.com/` from Safari. It's necessary to open and save from Safari because it saves certificate in binary format.
113 | - Press on lock icon in address bar
114 | - On showed popup press `Show Certificate`
115 | - Select botom one certificate in list and Drag-n-Drop certificate icon anywhare you need to save.
116 |
117 |
118 |
119 | 2. Add certificate to your project
120 | 3. Initialize our library providing path to this file
121 |
122 | Example with `Bundle` source path:
123 |
124 | ```Swift
125 | var openAI: OpenAIKit?
126 |
127 | if let filePath = Bundle.main.path(forResource: "MyCert", ofType: "cer") {
128 | openAI = OpenAIKit(apiToken: apiToken, organization: nil, sslCerificatePath: filePath)
129 | }
130 | ```
131 |
132 | Example with `FileManager` source path:
133 |
134 | ```Swift
135 | var openAI: OpenAIKit?
136 |
137 | let fileManager = FileManager.default
138 | let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as? NSString
139 |
140 | if let filePath = documentDirectoryPath?.appendingPathComponent("MyCert.cer") {
141 | openAI = OpenAIKit(apiToken: apiToken, organization: nil, sslCerificatePath: filePath)
142 | }
143 | ```
144 |
145 | ### Completions
146 | Create a call to the completions API, passing in a text prompt.
147 |
148 | ```swift
149 | openAI.sendCompletion(prompt: "Hello!", model: .gptV3_5(.davinciText003), maxTokens: 2048) { [weak self] result in
150 | switch result {
151 | case .success(let aiResult):
152 | DispatchQueue.main.async {
153 | if let text = aiResult.choices.first?.text {
154 | print("response text: \(text)") //"\n\nHello there, how may I assist you today?"
155 | }
156 | }
157 | case .failure(let error):
158 | DispatchQueue.main.async { [weak self] in
159 | let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
160 | alert.addAction(UIAlertAction(title: "Ok", style: .default))
161 | self?.present(alert, animated: true)
162 | }
163 | }
164 | }
165 | ```
166 |
167 | Also supports async/await usage for all methods. Here is example.
168 |
169 | ```swift
170 | let result = await openAI.sendCompletion(prompt: "Hello!", model: .gptV3_5(.davinciText003), maxTokens: 2048)
171 |
172 | switch result {
173 | case .success(let aiResult):
174 | /// Hadle success response result
175 | if let text = aiResult.choices.first?.text {
176 | print("response text: \(text)") //"\n\nHello there, how may I assist you today?"
177 | }
178 | case .failure(let error):
179 | /// Hadle error actions
180 | print(error.localizedDescription)
181 | }
182 | ```
183 | #### Chat Completions
184 | Chat completions almost the same as completions, there only few differences:
185 |
186 | - It can understand context with pathing previous chat messages ([read more](https://platform.openai.com/docs/guides/chat)).
187 | - Response text located in message field of retrieved completion
188 | - Supports **ONLY** *gpt-3.5-turbo* and *gpt-3.5-turbo-0301* models ([read more about models compatibility](https://platform.openai.com/docs/models/model-endpoint-compatability)).
189 |
190 | ```swift
191 | openAI.sendChatCompletion(newMessage: AIMessage(role: .user, content: prompt), previousMessages: [], model: .gptV3_5(.gptTurbo), maxTokens: 2048, n: 1, completion: { [weak self] result in
192 | DispatchQueue.main.async { self?.stopLoading() }
193 |
194 | switch result {
195 | case .success(let aiResult):
196 | // Handle result actions
197 | if let text = aiResult.choices.first?.message?.content {
198 | print(text)
199 | }
200 | case .failure(let error):
201 | // Handle error actions
202 | print(error.localizedDescription)
203 | }
204 | })
205 | ```
206 | #### Stream
207 | You can retrieve response from OpenAI for Completions and Chat Completions in stream partial progress. Don't need to wait time when whole completion response will complete. You can handle and present results in live.
208 |
209 | Example call on Chat Completions:
210 |
211 | ```swift
212 | openAI.sendStreamChatCompletion(newMessage: AIMessage(role: .user, content: "Hello!"), model: .gptV3_5(.gptTurbo), maxTokens: 2048) { result in
213 | switch result {
214 | case .success(let streamResult):
215 | /// Hadle success response result
216 | if let streamMessage = streamResult.message?.choices.first?.message {
217 | print("Stream message: \(streamMessage)") //"\n\nHello there, how may I assist you today?"
218 | }
219 | case .failure(let error):
220 | // Handle error actions
221 | print(error.localizedDescription)
222 | }
223 | }
224 | ```
225 |
226 | You can also stop stream manually like this:
227 |
228 | ```swift
229 | openAI.sendStreamChatCompletion(newMessage: AIMessage(role: .user, content: "Hello!"), model: .gptV3_5(.gptTurbo), maxTokens: 2048) { result in
230 | switch result {
231 | case .success(let streamResult):
232 | /// Hadle success response result
233 |
234 | streamResult.stream.stopStream() /// Manually stop stream
235 | case .failure(let error):
236 | // Handle error actions
237 | print(error.localizedDescription)
238 | }
239 | }
240 | ```
241 |
242 | #### JSON mode
243 |
244 | A common way to use Chat Completions is to instruct the model to always return a JSON object that makes sense for your use case, by specifying this in the system message.
245 | To prevent these errors and improve model performance, when calling gpt-4-turbo-preview or gpt-3.5-turbo-1106, you can set response_format to { "type": "json_object" } to enable JSON mode. When JSON mode is enabled, the model is constrained to only generate strings that parse into valid JSON object. More details in [OpenAI JSON mode](https://platform.openai.com/docs/guides/text-generation/json-mode) documentation.
246 |
247 | You can use it in `sendChatCompletion` or `sendStreamChatCompletion ` methods. Path optional parametr `responseFormat` to any of this methods
248 |
249 | ```swift
250 | openAI.sendChatCompletion(newMessage: AIMessage(role: .user, content: prompt), previousMessages: [], model: .gptV3_5(.gptTurbo), maxTokens: 2048, n: 1, responseFormat: .json, completion: { [weak self] result in
251 | DispatchQueue.main.async { self?.stopLoading() }
252 |
253 | switch result {
254 | case .success(let aiResult):
255 | // Handle result actions
256 | if let text = aiResult.choices.first?.message?.content {
257 | print(text) /// Printed JSON string
258 | }
259 | case .failure(let error):
260 | // Handle error actions
261 | print(error.localizedDescription)
262 | }
263 | })
264 | ```
265 |
266 | ### Generate Image
267 |
268 | [DALL·E](https://platform.openai.com/docs/models/dall-e) is a AI system that can create realistic images and art from a description in natural language. We currently support the ability, given a prommpt, to create a new image with a certain size, edit an existing image, or create variations of a user provided image.
269 |
270 | The code below demonstrates how you can generate an image using DALL·E:
271 |
272 | ```swift
273 | openAI.sendImagesRequest(prompt: "bird", size: .size512, n: 1) { [weak self] result in
274 |
275 | switch result {
276 | case .success(let aiResult):
277 |
278 | DispatchQueue.main.async {
279 | if let urlString = aiResult.data.first?.url {
280 | print("generated image url: \(urlString)")
281 | }
282 | }
283 | case .failure(let error):
284 | DispatchQueue.main.async { [weak self] in
285 | let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
286 | alert.addAction(UIAlertAction(title: "Ok", style: .default))
287 | self?.present(alert, animated: true)
288 | }
289 | }
290 | }
291 | ```
292 | ## Contribute
293 |
294 | Contributions for improvements are welcomed. Feel free to submit a pull request to help grow the library. If you have any questions, feature suggestions, or bug reports, please send them to [Issues](https://github.com/FuturraGroup/OpenAI/issues).
295 |
296 | ## License
297 |
298 | ```
299 | MIT License
300 |
301 | Copyright (c) 2023 Futurra Group
302 |
303 | Permission is hereby granted, free of charge, to any person obtaining a copy
304 | of this software and associated documentation files (the "Software"), to deal
305 | in the Software without restriction, including without limitation the rights
306 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
307 | copies of the Software, and to permit persons to whom the Software is
308 | furnished to do so, subject to the following conditions:
309 |
310 | The above copyright notice and this permission notice shall be included in all
311 | copies or substantial portions of the Software.
312 |
313 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
314 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
315 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
316 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
317 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
318 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
319 | SOFTWARE.
320 | ```
321 |
--------------------------------------------------------------------------------
/Example/OpenAIKit/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
--------------------------------------------------------------------------------
/Example/OpenAIKit.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
11 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
12 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
13 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
14 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
15 | 92178128F361F9174284E9A2 /* Pods_OpenAIKit_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C773545CB6B572C312902B7 /* Pods_OpenAIKit_Example.framework */; };
16 | A402FF1A29B5BF0B0008D484 /* ViewControllerImages.swift in Sources */ = {isa = PBXBuildFile; fileRef = A402FF1929B5BF0B0008D484 /* ViewControllerImages.swift */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | 353006538B3B7B1B4EC1C7BB /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; };
21 | 4404DA1264097869FD8F9A17 /* Pods-OpenAIKit_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenAIKit_Tests.debug.xcconfig"; path = "Target Support Files/Pods-OpenAIKit_Tests/Pods-OpenAIKit_Tests.debug.xcconfig"; sourceTree = ""; };
22 | 607FACD01AFB9204008FA782 /* OpenAIKit_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenAIKit_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
24 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
25 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
26 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
27 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
28 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
29 | 7C773545CB6B572C312902B7 /* Pods_OpenAIKit_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OpenAIKit_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
30 | 7F5010F3DC25DB71104222F3 /* Pods_OpenAIKit_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OpenAIKit_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31 | 89E7BCE4717AB352A90C79AC /* Pods-OpenAIKit_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenAIKit_Tests.release.xcconfig"; path = "Target Support Files/Pods-OpenAIKit_Tests/Pods-OpenAIKit_Tests.release.xcconfig"; sourceTree = ""; };
32 | A06687B527A549049A02A1AE /* OpenAIKit.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = OpenAIKit.podspec; path = ../OpenAIKit.podspec; sourceTree = ""; };
33 | A402FF1929B5BF0B0008D484 /* ViewControllerImages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerImages.swift; sourceTree = ""; };
34 | A9ACDFE51C218EAAF8993468 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; };
35 | B69B4F536C86F9D0E181D71C /* Pods-OpenAIKit_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenAIKit_Example.release.xcconfig"; path = "Target Support Files/Pods-OpenAIKit_Example/Pods-OpenAIKit_Example.release.xcconfig"; sourceTree = ""; };
36 | E19438361E65893CDD328D9A /* Pods-OpenAIKit_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenAIKit_Example.debug.xcconfig"; path = "Target Support Files/Pods-OpenAIKit_Example/Pods-OpenAIKit_Example.debug.xcconfig"; sourceTree = ""; };
37 | /* End PBXFileReference section */
38 |
39 | /* Begin PBXFrameworksBuildPhase section */
40 | 607FACCD1AFB9204008FA782 /* Frameworks */ = {
41 | isa = PBXFrameworksBuildPhase;
42 | buildActionMask = 2147483647;
43 | files = (
44 | 92178128F361F9174284E9A2 /* Pods_OpenAIKit_Example.framework in Frameworks */,
45 | );
46 | runOnlyForDeploymentPostprocessing = 0;
47 | };
48 | /* End PBXFrameworksBuildPhase section */
49 |
50 | /* Begin PBXGroup section */
51 | 607FACC71AFB9204008FA782 = {
52 | isa = PBXGroup;
53 | children = (
54 | 607FACF51AFB993E008FA782 /* Podspec Metadata */,
55 | 607FACD21AFB9204008FA782 /* Example for OpenAIKit */,
56 | 607FACD11AFB9204008FA782 /* Products */,
57 | ACCF50D69F2577FE6A3B5164 /* Pods */,
58 | B8F534E56F1EEDEF7B64A1B7 /* Frameworks */,
59 | );
60 | sourceTree = "";
61 | };
62 | 607FACD11AFB9204008FA782 /* Products */ = {
63 | isa = PBXGroup;
64 | children = (
65 | 607FACD01AFB9204008FA782 /* OpenAIKit_Example.app */,
66 | );
67 | name = Products;
68 | sourceTree = "";
69 | };
70 | 607FACD21AFB9204008FA782 /* Example for OpenAIKit */ = {
71 | isa = PBXGroup;
72 | children = (
73 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */,
74 | 607FACD71AFB9204008FA782 /* ViewController.swift */,
75 | A402FF1929B5BF0B0008D484 /* ViewControllerImages.swift */,
76 | 607FACDC1AFB9204008FA782 /* Images.xcassets */,
77 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */,
78 | 607FACD91AFB9204008FA782 /* Main.storyboard */,
79 | 607FACD31AFB9204008FA782 /* Supporting Files */,
80 | );
81 | name = "Example for OpenAIKit";
82 | path = OpenAIKit;
83 | sourceTree = "";
84 | };
85 | 607FACD31AFB9204008FA782 /* Supporting Files */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 607FACD41AFB9204008FA782 /* Info.plist */,
89 | );
90 | name = "Supporting Files";
91 | sourceTree = "";
92 | };
93 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = {
94 | isa = PBXGroup;
95 | children = (
96 | A06687B527A549049A02A1AE /* OpenAIKit.podspec */,
97 | A9ACDFE51C218EAAF8993468 /* README.md */,
98 | 353006538B3B7B1B4EC1C7BB /* LICENSE */,
99 | );
100 | name = "Podspec Metadata";
101 | sourceTree = "";
102 | };
103 | ACCF50D69F2577FE6A3B5164 /* Pods */ = {
104 | isa = PBXGroup;
105 | children = (
106 | E19438361E65893CDD328D9A /* Pods-OpenAIKit_Example.debug.xcconfig */,
107 | B69B4F536C86F9D0E181D71C /* Pods-OpenAIKit_Example.release.xcconfig */,
108 | 4404DA1264097869FD8F9A17 /* Pods-OpenAIKit_Tests.debug.xcconfig */,
109 | 89E7BCE4717AB352A90C79AC /* Pods-OpenAIKit_Tests.release.xcconfig */,
110 | );
111 | path = Pods;
112 | sourceTree = "";
113 | };
114 | B8F534E56F1EEDEF7B64A1B7 /* Frameworks */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 7C773545CB6B572C312902B7 /* Pods_OpenAIKit_Example.framework */,
118 | 7F5010F3DC25DB71104222F3 /* Pods_OpenAIKit_Tests.framework */,
119 | );
120 | name = Frameworks;
121 | sourceTree = "";
122 | };
123 | /* End PBXGroup section */
124 |
125 | /* Begin PBXNativeTarget section */
126 | 607FACCF1AFB9204008FA782 /* OpenAIKit_Example */ = {
127 | isa = PBXNativeTarget;
128 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "OpenAIKit_Example" */;
129 | buildPhases = (
130 | 9658B17C80C8C74359767F78 /* [CP] Check Pods Manifest.lock */,
131 | 607FACCC1AFB9204008FA782 /* Sources */,
132 | 607FACCD1AFB9204008FA782 /* Frameworks */,
133 | 607FACCE1AFB9204008FA782 /* Resources */,
134 | A629922A3A225228C93200AA /* [CP] Embed Pods Frameworks */,
135 | );
136 | buildRules = (
137 | );
138 | dependencies = (
139 | );
140 | name = OpenAIKit_Example;
141 | productName = OpenAIKit;
142 | productReference = 607FACD01AFB9204008FA782 /* OpenAIKit_Example.app */;
143 | productType = "com.apple.product-type.application";
144 | };
145 | /* End PBXNativeTarget section */
146 |
147 | /* Begin PBXProject section */
148 | 607FACC81AFB9204008FA782 /* Project object */ = {
149 | isa = PBXProject;
150 | attributes = {
151 | LastSwiftUpdateCheck = 0830;
152 | LastUpgradeCheck = 1420;
153 | ORGANIZATIONNAME = "Futurra Group";
154 | TargetAttributes = {
155 | 607FACCF1AFB9204008FA782 = {
156 | CreatedOnToolsVersion = 6.3.1;
157 | DevelopmentTeam = 358DXRMT22;
158 | LastSwiftMigration = "";
159 | };
160 | };
161 | };
162 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "OpenAIKit" */;
163 | compatibilityVersion = "Xcode 3.2";
164 | developmentRegion = English;
165 | hasScannedForEncodings = 0;
166 | knownRegions = (
167 | English,
168 | en,
169 | Base,
170 | );
171 | mainGroup = 607FACC71AFB9204008FA782;
172 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
173 | projectDirPath = "";
174 | projectRoot = "";
175 | targets = (
176 | 607FACCF1AFB9204008FA782 /* OpenAIKit_Example */,
177 | );
178 | };
179 | /* End PBXProject section */
180 |
181 | /* Begin PBXResourcesBuildPhase section */
182 | 607FACCE1AFB9204008FA782 /* Resources */ = {
183 | isa = PBXResourcesBuildPhase;
184 | buildActionMask = 2147483647;
185 | files = (
186 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
187 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
188 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */,
189 | );
190 | runOnlyForDeploymentPostprocessing = 0;
191 | };
192 | /* End PBXResourcesBuildPhase section */
193 |
194 | /* Begin PBXShellScriptBuildPhase section */
195 | 9658B17C80C8C74359767F78 /* [CP] Check Pods Manifest.lock */ = {
196 | isa = PBXShellScriptBuildPhase;
197 | buildActionMask = 2147483647;
198 | files = (
199 | );
200 | inputFileListPaths = (
201 | );
202 | inputPaths = (
203 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
204 | "${PODS_ROOT}/Manifest.lock",
205 | );
206 | name = "[CP] Check Pods Manifest.lock";
207 | outputFileListPaths = (
208 | );
209 | outputPaths = (
210 | "$(DERIVED_FILE_DIR)/Pods-OpenAIKit_Example-checkManifestLockResult.txt",
211 | );
212 | runOnlyForDeploymentPostprocessing = 0;
213 | shellPath = /bin/sh;
214 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
215 | showEnvVarsInLog = 0;
216 | };
217 | A629922A3A225228C93200AA /* [CP] Embed Pods Frameworks */ = {
218 | isa = PBXShellScriptBuildPhase;
219 | buildActionMask = 2147483647;
220 | files = (
221 | );
222 | inputPaths = (
223 | "${PODS_ROOT}/Target Support Files/Pods-OpenAIKit_Example/Pods-OpenAIKit_Example-frameworks.sh",
224 | "${BUILT_PRODUCTS_DIR}/OpenAIKit/OpenAIKit.framework",
225 | "${BUILT_PRODUCTS_DIR}/SDWebImage/SDWebImage.framework",
226 | );
227 | name = "[CP] Embed Pods Frameworks";
228 | outputPaths = (
229 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenAIKit.framework",
230 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
231 | );
232 | runOnlyForDeploymentPostprocessing = 0;
233 | shellPath = /bin/sh;
234 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OpenAIKit_Example/Pods-OpenAIKit_Example-frameworks.sh\"\n";
235 | showEnvVarsInLog = 0;
236 | };
237 | /* End PBXShellScriptBuildPhase section */
238 |
239 | /* Begin PBXSourcesBuildPhase section */
240 | 607FACCC1AFB9204008FA782 /* Sources */ = {
241 | isa = PBXSourcesBuildPhase;
242 | buildActionMask = 2147483647;
243 | files = (
244 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
245 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
246 | A402FF1A29B5BF0B0008D484 /* ViewControllerImages.swift in Sources */,
247 | );
248 | runOnlyForDeploymentPostprocessing = 0;
249 | };
250 | /* End PBXSourcesBuildPhase section */
251 |
252 | /* Begin PBXVariantGroup section */
253 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = {
254 | isa = PBXVariantGroup;
255 | children = (
256 | 607FACDA1AFB9204008FA782 /* Base */,
257 | );
258 | name = Main.storyboard;
259 | sourceTree = "";
260 | };
261 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = {
262 | isa = PBXVariantGroup;
263 | children = (
264 | 607FACDF1AFB9204008FA782 /* Base */,
265 | );
266 | name = LaunchScreen.xib;
267 | sourceTree = "";
268 | };
269 | /* End PBXVariantGroup section */
270 |
271 | /* Begin XCBuildConfiguration section */
272 | 607FACED1AFB9204008FA782 /* Debug */ = {
273 | isa = XCBuildConfiguration;
274 | buildSettings = {
275 | ALWAYS_SEARCH_USER_PATHS = NO;
276 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
277 | CLANG_CXX_LIBRARY = "libc++";
278 | CLANG_ENABLE_MODULES = YES;
279 | CLANG_ENABLE_OBJC_ARC = YES;
280 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
281 | CLANG_WARN_BOOL_CONVERSION = YES;
282 | CLANG_WARN_COMMA = YES;
283 | CLANG_WARN_CONSTANT_CONVERSION = YES;
284 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
285 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
286 | CLANG_WARN_EMPTY_BODY = YES;
287 | CLANG_WARN_ENUM_CONVERSION = YES;
288 | CLANG_WARN_INFINITE_RECURSION = YES;
289 | CLANG_WARN_INT_CONVERSION = YES;
290 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
291 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
292 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
293 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
294 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
295 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
296 | CLANG_WARN_STRICT_PROTOTYPES = YES;
297 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
298 | CLANG_WARN_UNREACHABLE_CODE = YES;
299 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
300 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
301 | COPY_PHASE_STRIP = NO;
302 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
303 | ENABLE_STRICT_OBJC_MSGSEND = YES;
304 | ENABLE_TESTABILITY = YES;
305 | GCC_C_LANGUAGE_STANDARD = gnu99;
306 | GCC_DYNAMIC_NO_PIC = NO;
307 | GCC_NO_COMMON_BLOCKS = YES;
308 | GCC_OPTIMIZATION_LEVEL = 0;
309 | GCC_PREPROCESSOR_DEFINITIONS = (
310 | "DEBUG=1",
311 | "$(inherited)",
312 | );
313 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
314 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
315 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
316 | GCC_WARN_UNDECLARED_SELECTOR = YES;
317 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
318 | GCC_WARN_UNUSED_FUNCTION = YES;
319 | GCC_WARN_UNUSED_VARIABLE = YES;
320 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
321 | MTL_ENABLE_DEBUG_INFO = YES;
322 | ONLY_ACTIVE_ARCH = YES;
323 | SDKROOT = iphoneos;
324 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
325 | };
326 | name = Debug;
327 | };
328 | 607FACEE1AFB9204008FA782 /* Release */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ALWAYS_SEARCH_USER_PATHS = NO;
332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
333 | CLANG_CXX_LIBRARY = "libc++";
334 | CLANG_ENABLE_MODULES = YES;
335 | CLANG_ENABLE_OBJC_ARC = YES;
336 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
337 | CLANG_WARN_BOOL_CONVERSION = YES;
338 | CLANG_WARN_COMMA = YES;
339 | CLANG_WARN_CONSTANT_CONVERSION = YES;
340 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
341 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
342 | CLANG_WARN_EMPTY_BODY = YES;
343 | CLANG_WARN_ENUM_CONVERSION = YES;
344 | CLANG_WARN_INFINITE_RECURSION = YES;
345 | CLANG_WARN_INT_CONVERSION = YES;
346 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
347 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
348 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
349 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
350 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
351 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
352 | CLANG_WARN_STRICT_PROTOTYPES = YES;
353 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
354 | CLANG_WARN_UNREACHABLE_CODE = YES;
355 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
356 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
357 | COPY_PHASE_STRIP = NO;
358 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
359 | ENABLE_NS_ASSERTIONS = NO;
360 | ENABLE_STRICT_OBJC_MSGSEND = YES;
361 | GCC_C_LANGUAGE_STANDARD = gnu99;
362 | GCC_NO_COMMON_BLOCKS = YES;
363 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
364 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
365 | GCC_WARN_UNDECLARED_SELECTOR = YES;
366 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
367 | GCC_WARN_UNUSED_FUNCTION = YES;
368 | GCC_WARN_UNUSED_VARIABLE = YES;
369 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
370 | MTL_ENABLE_DEBUG_INFO = NO;
371 | SDKROOT = iphoneos;
372 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
373 | VALIDATE_PRODUCT = YES;
374 | };
375 | name = Release;
376 | };
377 | 607FACF01AFB9204008FA782 /* Debug */ = {
378 | isa = XCBuildConfiguration;
379 | baseConfigurationReference = E19438361E65893CDD328D9A /* Pods-OpenAIKit_Example.debug.xcconfig */;
380 | buildSettings = {
381 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
382 | DEVELOPMENT_TEAM = 358DXRMT22;
383 | INFOPLIST_FILE = OpenAIKit/Info.plist;
384 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
385 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
386 | MODULE_NAME = ExampleApp;
387 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
388 | PRODUCT_NAME = "$(TARGET_NAME)";
389 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
390 | SWIFT_VERSION = 5.0;
391 | };
392 | name = Debug;
393 | };
394 | 607FACF11AFB9204008FA782 /* Release */ = {
395 | isa = XCBuildConfiguration;
396 | baseConfigurationReference = B69B4F536C86F9D0E181D71C /* Pods-OpenAIKit_Example.release.xcconfig */;
397 | buildSettings = {
398 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
399 | DEVELOPMENT_TEAM = 358DXRMT22;
400 | INFOPLIST_FILE = OpenAIKit/Info.plist;
401 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
402 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
403 | MODULE_NAME = ExampleApp;
404 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
405 | PRODUCT_NAME = "$(TARGET_NAME)";
406 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
407 | SWIFT_VERSION = 5.0;
408 | };
409 | name = Release;
410 | };
411 | /* End XCBuildConfiguration section */
412 |
413 | /* Begin XCConfigurationList section */
414 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "OpenAIKit" */ = {
415 | isa = XCConfigurationList;
416 | buildConfigurations = (
417 | 607FACED1AFB9204008FA782 /* Debug */,
418 | 607FACEE1AFB9204008FA782 /* Release */,
419 | );
420 | defaultConfigurationIsVisible = 0;
421 | defaultConfigurationName = Release;
422 | };
423 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "OpenAIKit_Example" */ = {
424 | isa = XCConfigurationList;
425 | buildConfigurations = (
426 | 607FACF01AFB9204008FA782 /* Debug */,
427 | 607FACF11AFB9204008FA782 /* Release */,
428 | );
429 | defaultConfigurationIsVisible = 0;
430 | defaultConfigurationName = Release;
431 | };
432 | /* End XCConfigurationList section */
433 | };
434 | rootObject = 607FACC81AFB9204008FA782 /* Project object */;
435 | }
436 |
--------------------------------------------------------------------------------