Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .cursor/rules/cloudinary.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
description: Cloudinary cloudinary_ios — agent guide
alwaysApply: true
---

Read and follow `AGENTS.md` in the repository root. It is the single
authoritative guide for this package: build/test commands, conventions,
gotchas, and when to use this SDK versus a sibling Cloudinary package.
5 changes: 5 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Cloudinary cloudinary_ios — instructions for AI coding agents

Read `AGENTS.md` in the repository root and follow it. It is the single
authoritative guide for this package: build/test commands, conventions,
gotchas, and when to use this SDK versus a sibling Cloudinary package.
105 changes: 105 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!--
AGENTS.md for cloudinary/cloudinary_ios — for AI coding agents working IN this repo.
Human "what is this" content stays in README.md. Keep under ~10 KB.
-->

# AGENTS.md — cloudinary_ios

## What this package is (one line)
Official Cloudinary native iOS client SDK (`Cloudinary`): on-device upload (signed/unsigned), delivery + transformation URL building with `CLDTransformation`, and image download with memory/disk caching — in Swift or Objective-C.

## When to use this / when NOT to use this
- **Use this when:** you are building a native iOS app (Swift or Objective-C) and need to upload media from the device, build delivery/transformation URLs, or download and cache images on-device.
- **Do NOT use this when:** you are building a cross-platform React Native app (use [cloudinary-react-native](https://github.com/cloudinary/cloudinary-react-native)); OR you need server-side work — signed uploads from a server, the Admin API, or anything touching `API_SECRET` (use a backend SDK such as [cloudinary_npm](https://github.com/cloudinary/cloudinary_npm)). A secret must never ship inside an app binary.
- **Sibling packages:** `cloudinary_android` = the same SDK for native Android; `cloudinary-react-native` = React Native (iOS + Android); `cloudinary-ios-sample-app` = a complete runnable example app (learn from it, don't depend on it). This repo's own runnable demo lives in `Example/`.

## Setup
This SDK is consumed as a dependency. Pick one:

```ruby
# CocoaPods — in your Podfile
platform :ios, '9.0'
use_frameworks!
target 'MyApp' do
pod 'Cloudinary', '~> 5.0'
end
```
```
# Swift Package Manager — Xcode > File > Add Packages...
https://github.com/cloudinary/cloudinary_ios.git (Up to Next Major, 5.0.0)
```
```
# Carthage — in your Cartfile
github "cloudinary/cloudinary_ios" ~> 5.0
# then: carthage update --use-xcframeworks
```

Required configuration: a `cloudName` and `apiKey` only (client-side). No `API_SECRET`.

## Minimal runnable example
```swift
import Cloudinary

let config = CLDConfiguration(cloudName: "CLOUD_NAME", apiKey: "API_KEY")
let cloudinary = CLDCloudinary(configuration: config)

// Build a delivery URL
let t = CLDTransformation().setWidth(100).setHeight(150).setCrop(.fill)
let url = cloudinary.createUrl().setTransformation(t).generate("sample.jpg")
// http://res.cloudinary.com/CLOUD_NAME/image/upload/c_fill,h_150,w_100/sample.jpg

// Unsigned upload via an upload preset (no secret needed).
// CLDUploader exposes upload(url:) and upload(data:) — there is no upload(file:).
cloudinary.createUploader().upload(url: fileUrl, uploadPreset: "sample_preset")
```

## Build / test commands (run these after editing)
There is no `xcodebuild` target at the repo root. The library source is built and exercised through the `Example/` project, which is what CI runs. Tests need a Cloudinary account.

```bash
# 1. Install the Example workspace deps (generates Example/Cloudinary.xcworkspace)
pod install --project-directory=Example

# 2. Tests require a live account — set this before running them
export CLOUDINARY_URL="cloudinary://<api_key>:<api_secret>@<cloud_name>"

# 3. Build + run the test suite (mirrors CI; pick an installed simulator/OS)
xcodebuild test \
-workspace Example/Cloudinary.xcworkspace \
-scheme travis_public_scheme \
-destination 'platform=iOS Simulator,OS=15.2,name=iPhone 8'
```
To run a **single** test class or method, append `-only-testing:` (target/class/method):

```bash
xcodebuild test \
-workspace Example/Cloudinary.xcworkspace \
-scheme travis_public_scheme \
-destination 'platform=iOS Simulator,OS=15.2,name=iPhone 8' \
-only-testing:Cloudinary_Tests/CLDConditionExpressionTests
```

SwiftPM consumers can also build the library directly: `swift build`. Note that CI does **not** exercise SwiftPM — it builds only the `Example/Cloudinary.xcworkspace` (`travis_public_scheme`) — so verify `swift build` locally if you touch `Package.swift` or its sources.

No lint step is configured in this repo — there is no SwiftLint or SwiftFormat config in the tree, and CI runs none. Match the surrounding code style by hand.

## Conventions & gotchas
- **Never put `API_SECRET` in the app.** Configure with `cloudName` + `apiKey` and use unsigned uploads (upload presets). Signed uploads and Admin API calls belong on a backend. The `cloudinary://key:secret@cloud` form and `CLOUDINARY_URL` env var exist for *test* configuration only — don't bake a secret into a shipped binary.
- **Minimum deployment target is iOS 9.0; Swift version 5.0** (from `Cloudinary.podspec` and `Package.swift`). Don't raise the floor or use APIs unavailable at iOS 9 without intent. SDK 3.0+ dropped iOS 8.
- **Library source lives under `Cloudinary/`; tests and the demo app live under `Example/`.** Add new tests under `Example/Tests/...` (mirror the existing folders, e.g. `NetworkTests`, `TransformationTests`). There are paired Swift + Objective-C tests (`*.swift` and `*.m`) — keep the Objective-C interop surface working.
- **All public types are prefixed `CLD`** (`CLDCloudinary`, `CLDConfiguration`, `CLDTransformation`, `CLDUploadRequestParams`, …). Follow that prefix for new public API.
- **CI is Travis** (`.travis.yml`), not GitHub Actions — it runs the `Example` workspace `travis_public_scheme` across several Xcode/iOS-simulator combos and injects `CLOUDINARY_URL`. Network tests fail without a configured account.

## Canonical docs (leave the repo for depth)
- iOS SDK guide: https://cloudinary.com/documentation/ios_integration
- Image/video upload: https://cloudinary.com/documentation/ios_image_and_video_upload
- Transformation & API references: https://cloudinary.com/documentation/cloudinary_references
- MCP server (agent/no-code path): https://github.com/cloudinary/mcp-servers

## Agent / MCP note
If a task is exposed via the Cloudinary MCP servers, prefer the MCP tool for autonomous task execution and use this SDK for code generation inside an iOS app. See cloudinary/mcp-servers.

## Commit / PR conventions
- Open PRs against the default branch; keep Swift + Objective-C test parity green.
- Add or update tests under `Example/Tests/` for any behavior change; CI must pass on the `Example` workspace.
- There is no `CONTRIBUTING.md` in this repo, but `.github/` provides an issue template and a `pull_request_template.md` — fill the PR template out. No commit-message convention (e.g. Conventional Commits) is configured or enforced.
43 changes: 43 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@AGENTS.md

# CLAUDE.md — cloudinary_ios

## What this repo is

Official native iOS client SDK (`Cloudinary` pod / SPM package) for Cloudinary — on-device upload, `CLDTransformation`-based delivery URL building, and image download with memory/disk cache, in Swift or Objective-C.

## Key constraints / gotchas

- **Never put `API_SECRET` in the app.** Client configuration is `cloudName` + `apiKey` only. Signed uploads and Admin API calls belong on a backend. `CLOUDINARY_URL` with a secret is for *test* configuration only.
- **Minimum iOS 9.0, Swift 5.0.** SDK 3.0+ dropped iOS 8; don't raise the deployment floor without intent.
- **Library source in `Cloudinary/`; tests and demo in `Example/`.** Add new tests under `Example/Tests/` — keep Swift + Objective-C parity.
- **All public types are prefixed `CLD`** (`CLDCloudinary`, `CLDConfiguration`, `CLDTransformation`, …). Follow the prefix for any new public API.
- **No `upload(file:)`.** Real labels: `upload(url:uploadPreset:)` / `upload(data:uploadPreset:)` (unsigned) and `signedUpload(url:)` / `signedUpload(data:)` (signed). For large files: `uploadLarge` / `signedUploadLarge`.
- **Enum cases are lowercase/camelCase**, not capitalized. Use `.fill`, `.fit`, `.face`, `.northWest` — not `.Fill`, `.NorthWest`.
- **`setTransformation` requires a `CLDTransformation` argument** — there is no zero-argument overload.
- **CI is Travis** (`.travis.yml`), not GitHub Actions. It builds only the `Example/Cloudinary.xcworkspace` (`travis_public_scheme`). SwiftPM builds are not CI-verified.
- **No lint config.** No SwiftLint or SwiftFormat in the tree. Match surrounding style by hand.

## Build / test commands

```bash
# Install Example workspace deps
pod install --project-directory=Example

# Run full test suite (requires live Cloudinary account)
export CLOUDINARY_URL="cloudinary://<api_key>:<api_secret>@<cloud_name>"
xcodebuild test \
-workspace Example/Cloudinary.xcworkspace \
-scheme travis_public_scheme \
-destination 'platform=iOS Simulator,OS=15.2,name=iPhone 8'

# Run a single test class
xcodebuild test \
-workspace Example/Cloudinary.xcworkspace \
-scheme travis_public_scheme \
-destination 'platform=iOS Simulator,OS=15.2,name=iPhone 8' \
-only-testing:Cloudinary_Tests/CLDConditionExpressionTests

# SwiftPM build (not CI-verified — check locally when touching Package.swift)
swift build
```
Loading