@@ -1707,6 +1707,90 @@ Use the file URL returned from the snippet above.
1707
1707
}
1708
1708
```
1709
1709
1710
+ ### How to use structured ouputs and an image as input with Gemini
1711
+
1712
+ ``` swift
1713
+ import AIProxy
1714
+
1715
+ /* Uncomment for BYOK use cases */
1716
+ // let geminiService = AIProxy.geminiDirectService(
1717
+ // unprotectedAPIKey: "your-gemini-key"
1718
+ // )
1719
+
1720
+ /* Uncomment for all other production use cases */
1721
+ // let geminiService = AIProxy.geminiService(
1722
+ // partialKey: "partial-key-from-your-developer-dashboard",
1723
+ // serviceURL: "service-url-from-your-developer-dashboard"
1724
+ // )
1725
+
1726
+ guard let image = NSImage (named : " apple_marketing" ) else {
1727
+ print (" Could not find an image named 'apple_marketing' in your app assets" )
1728
+ return
1729
+ }
1730
+
1731
+ guard let jpegData = AIProxy.encodeImageAsJpeg (image : image, compressionQuality : 0.4 ) else {
1732
+ print (" Could not encode image as Jpeg" )
1733
+ return
1734
+ }
1735
+
1736
+ let schema: [String : AIProxyJSONValue] = [
1737
+ " description" : " A list of the important points that the document conveys" ,
1738
+ " type" : " array" ,
1739
+ " items" : [
1740
+ " type" : " object" ,
1741
+ " properties" : [
1742
+ " point" : [
1743
+ " type" : " string" ,
1744
+ " description" : " One of the important points that the document conveys" ,
1745
+ " nullable" : false
1746
+ ]
1747
+ ],
1748
+ " required" : [" point" ]
1749
+ ]
1750
+ ]
1751
+
1752
+ let requestBody = GeminiGenerateContentRequestBody (
1753
+ contents : [
1754
+ .init (
1755
+ parts : [
1756
+ .text (" Please create the important points of this image" ),
1757
+ .inline (
1758
+ data : jpegData,
1759
+ mimeType : " image/jpeg"
1760
+ )
1761
+ ]
1762
+ )
1763
+ ],
1764
+ generationConfig : .init (
1765
+ responseMimeType : " application/json" ,
1766
+ responseSchema : schema
1767
+ ),
1768
+ safetySettings : [
1769
+ .init (category : .dangerousContent , threshold : .none ),
1770
+ .init (category : .civicIntegrity , threshold : .none ),
1771
+ .init (category : .harassment , threshold : .none ),
1772
+ .init (category : .hateSpeech , threshold : .none ),
1773
+ .init (category : .sexuallyExplicit , threshold : .none )
1774
+ ]
1775
+ )
1776
+
1777
+ do {
1778
+ let response = try await geminiService.generateContentRequest (
1779
+ body : requestBody,
1780
+ model : " gemini-2.0-flash"
1781
+ )
1782
+ for part in response.candidates? .first ? .content? .parts ?? [] {
1783
+ if case .text (let text) = part {
1784
+ print (" Gemini sent: \( text ) " )
1785
+ }
1786
+ }
1787
+ } catch AIProxyError.unsuccessfulRequest (let statusCode, let responseBody) {
1788
+ print (" Received \( statusCode ) status code with response body: \( responseBody ) " )
1789
+ } catch {
1790
+ print (" Could not create Gemini generate content request: \( error.localizedDescription ) " )
1791
+ }
1792
+ ```
1793
+
1710
1794
1711
1795
***
1712
1796
0 commit comments