├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── pull_request_template.md ├── .gitignore ├── .gitmodules ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── .travis.yml ├── CHANGELOG.md ├── Cloudinary.podspec ├── Cloudinary.xcodeproj ├── Cloudinary_Info.plist ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── xcshareddata │ └── xcschemes │ └── Cloudinary-Package.xcscheme ├── Cloudinary ├── Assets │ └── .gitkeep └── Classes │ ├── Core │ ├── BaseNetwork │ │ ├── CLDNConvertible.swift │ │ ├── CLDNError.swift │ │ ├── CLDNMultipartFormData.swift │ │ ├── CLDNParameterEncoding.swift │ │ ├── CLDNRequest.swift │ │ ├── CLDNResponse.swift │ │ ├── CLDNResponseSerialization.swift │ │ ├── CLDNResult.swift │ │ ├── CLDNSessionDelegate.swift │ │ ├── CLDNSessionManager.swift │ │ ├── CLDNTaskDelegate.swift │ │ ├── CLDNTimeline.swift │ │ ├── CLDNValidation.swift │ │ └── DispatchQueue+Cloudinary.swift │ ├── CLDAnalytics.swift │ ├── CLDCloudinary.swift │ ├── CLDCompatibility.swift │ ├── CLDConfiguration.swift │ ├── CLDEagerTransformation.swift │ ├── CLDResponsiveParams.swift │ ├── Cloudinary.h │ ├── Features │ │ ├── CacheSystem │ │ │ └── Enum │ │ │ │ └── HTTPStatusCode.swift │ │ ├── Downloader │ │ │ └── CLDDownloader.swift │ │ ├── Helpers │ │ │ ├── CLDBaseNetworkObject.swift │ │ │ ├── CLDConditionExpression.swift │ │ │ ├── CLDDefinitions.swift │ │ │ ├── CLDExpression.swift │ │ │ ├── CLDOperators.swift │ │ │ ├── CLDTransformation.swift │ │ │ ├── CLDVariable.swift │ │ │ ├── Layers │ │ │ │ ├── CLDFetchLayer.swift │ │ │ │ ├── CLDLayer.swift │ │ │ │ ├── CLDSubtitlesLayer.swift │ │ │ │ └── CLDTextLayer.swift │ │ │ ├── RequestParams │ │ │ │ ├── CLDRequestParams.swift │ │ │ │ └── Helpers │ │ │ │ │ └── CLDRequestParamsHelpers.swift │ │ │ ├── Requests │ │ │ │ └── CLDRequest.swift │ │ │ └── Results │ │ │ │ ├── CLDBaseResult.swift │ │ │ │ └── Helpers │ │ │ │ ├── AccessibilityAnalysis │ │ │ │ ├── CLDAccessibilityAnalysisResult.swift │ │ │ │ └── CLDColorblindAccessibilityAnalysisResult.swift │ │ │ │ ├── CLDBoundingBox.swift │ │ │ │ ├── CLDDetection.swift │ │ │ │ ├── CLDFace.swift │ │ │ │ ├── CLDInfo.swift │ │ │ │ ├── CLDOcr │ │ │ │ ├── CLDAdvOcrResult.swift │ │ │ │ ├── CLDOcrBlockResult.swift │ │ │ │ ├── CLDOcrBoundindBlockResult.swift │ │ │ │ ├── CLDOcrDataResult.swift │ │ │ │ ├── CLDOcrDetectedLanguagesResult.swift │ │ │ │ ├── CLDOcrFullTextAnnotationResult.swift │ │ │ │ ├── CLDOcrPageResult.swift │ │ │ │ ├── CLDOcrParagraphResult.swift │ │ │ │ ├── CLDOcrPropertyResult.swift │ │ │ │ ├── CLDOcrResult.swift │ │ │ │ ├── CLDOcrSymbolResult.swift │ │ │ │ ├── CLDOcrTextAnnotationResult.swift │ │ │ │ └── CLDOcrWordResult.swift │ │ │ │ ├── CLDQualityAnalysis │ │ │ │ └── CLDQualityAnalysis.swift │ │ │ │ ├── CLDRekognitionFace.swift │ │ │ │ └── CommonResultKeys.swift │ │ ├── ManagementApi │ │ │ ├── CLDManagementApi.swift │ │ │ ├── Requests │ │ │ │ ├── CLDDeleteRequest.swift │ │ │ │ ├── CLDExplicitRequest.swift │ │ │ │ ├── CLDExplodeRequest.swift │ │ │ │ ├── CLDMultiRequest.swift │ │ │ │ ├── CLDRenameRequest.swift │ │ │ │ ├── CLDSpriteRequest.swift │ │ │ │ ├── CLDTagRequest.swift │ │ │ │ └── CLDTextRequest.swift │ │ │ ├── RequestsParams │ │ │ │ ├── CLDDeleteByTokenRequestParams.swift │ │ │ │ ├── CLDDestroyRequestParams.swift │ │ │ │ ├── CLDExplicitRequestParams.swift │ │ │ │ ├── CLDExplodeRequestParams.swift │ │ │ │ ├── CLDMultiRequestParams.swift │ │ │ │ ├── CLDRenameRequestParams.swift │ │ │ │ ├── CLDSpriteRequestParams.swift │ │ │ │ ├── CLDTagsRequestParams.swift │ │ │ │ └── CLDTextRequestParams.swift │ │ │ └── Results │ │ │ │ ├── CLDDeleteResult.swift │ │ │ │ ├── CLDExplicitResult.swift │ │ │ │ ├── CLDExplodeResult.swift │ │ │ │ ├── CLDMultiResult.swift │ │ │ │ ├── CLDRenameResult.swift │ │ │ │ ├── CLDSpriteResult.swift │ │ │ │ ├── CLDTagResult.swift │ │ │ │ └── CLDTextResult.swift │ │ ├── UploadWidget │ │ │ ├── CLDUploaderWidget.swift │ │ │ ├── CropView │ │ │ │ ├── CLDCropOverlayView.swift │ │ │ │ ├── CLDCropScrollView.swift │ │ │ │ ├── CLDCropScrollViewController.swift │ │ │ │ ├── CLDCropView.swift │ │ │ │ ├── CLDCropViewCalculator.swift │ │ │ │ └── CLDCropViewUIManager.swift │ │ │ ├── WidgetConfiguration │ │ │ │ └── CLDWidgetConfiguration.swift │ │ │ ├── WidgetElements │ │ │ │ ├── CLDWidgetAssetContainer.swift │ │ │ │ └── CLDWidgetPreviewCollectionCell.swift │ │ │ ├── WidgetImages │ │ │ │ ├── BackIconInstructions.swift │ │ │ │ ├── CropIconInstructions.swift │ │ │ │ ├── CropRotateIconInstructions.swift │ │ │ │ ├── DoneIconInstructions.swift │ │ │ │ ├── RatioLockedIconInstructions.swift │ │ │ │ ├── RatioOpenedIconInstructions.swift │ │ │ │ └── RotateIconInstructions.swift │ │ │ ├── WidgetVideo │ │ │ │ ├── CLDDisplayLinkObserver.swift │ │ │ │ ├── CLDVideoControlsState.swift │ │ │ │ ├── CLDVideoControlsView.swift │ │ │ │ ├── CLDVideoHiddenAndPausedState.swift │ │ │ │ ├── CLDVideoHiddenAndPlayingState.swift │ │ │ │ ├── CLDVideoPlayerView.swift │ │ │ │ ├── CLDVideoShownAndPausedState.swift │ │ │ │ ├── CLDVideoShownAndPlayingState.swift │ │ │ │ └── CLDVideoView.swift │ │ │ └── WidgetViewControllers │ │ │ │ ├── CLDWidgetEditViewController.swift │ │ │ │ ├── CLDWidgetPreviewViewController.swift │ │ │ │ └── CLDWidgetViewController.swift │ │ ├── Uploader │ │ │ ├── CLDUploader.swift │ │ │ ├── Preupload │ │ │ │ └── CLDPreprocessChain.swift │ │ │ ├── RequestParams │ │ │ │ └── CLDUploadRequestParams.swift │ │ │ ├── Requests │ │ │ │ ├── CLDDefaultUploadRequest.swift │ │ │ │ ├── CLDUploadRequest.swift │ │ │ │ └── CLDUploadRequestWrapper.swift │ │ │ └── Results │ │ │ │ └── CLDUploadResult.swift │ │ └── Url │ │ │ └── CLDUrl.swift │ ├── Network │ │ ├── Adapter │ │ │ └── CLDNetworkAdapter.swift │ │ ├── CLDDefaultNetworkAdapter.swift │ │ ├── CLDNetworkCoordinator.swift │ │ ├── NetworkRequest │ │ │ ├── CLDAsyncNetworkUploadRequest.swift │ │ │ ├── CLDErrorRequest.swift │ │ │ ├── CLDGenericNetworkRequest.swift │ │ │ ├── CLDNetworkDataRequestImpl.swift │ │ │ ├── CLDNetworkDownloadRequest.swift │ │ │ └── CLDNetworkUploadRequest.swift │ │ └── PrivacyInfo.xcprivacy │ └── Utils │ │ ├── CLDBuildParamsUtils.swift │ │ ├── CLDCryptoUtils.swift │ │ ├── CLDDictionaryUtils.swift │ │ ├── CLDError.swift │ │ ├── CLDFileUtils.swift │ │ ├── CLDImageGenerator │ │ └── CLDImageGenerator.swift │ │ ├── CLDImageUtils.swift │ │ ├── CLDJsonUtils.swift │ │ ├── CLDLogManager.swift │ │ └── CLDStringUtils.swift │ └── ios │ ├── Extensions │ ├── CLDTransformation+Ios.swift │ ├── ExtensionCLDDownloader.swift │ ├── UIButton+Cloudinary.swift │ ├── UIImageView+Cloudinary.swift │ └── UIView+Cloudinary.swift │ ├── NetworkRequest │ ├── CLDFetchAssetRequestImpl.swift │ └── CLDFetchImageRequestImpl.swift │ ├── UIViews │ ├── CLDResponsiveViewHelper.swift │ └── CLDUIImageView.swift │ ├── Uploader │ ├── CLDImagePreprocessChain.swift │ ├── CLDPreprocessHelpers.swift │ ├── CLDVideoPreprocessChain.swift │ ├── CLDVideoPreprocessHelpers.swift │ └── CLDVideoTranscode.swift │ └── Video │ ├── Analytics │ ├── VideoAnalytics.swift │ └── VideoEventsManager.swift │ └── CLDVideoPlayer.swift ├── Example ├── Cloudinary.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ ├── Cloudinary-Example.xcscheme │ │ └── travis_public_scheme.xcscheme ├── Cloudinary │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ └── app_icon 1.heic │ │ ├── Contents.json │ │ ├── Delivery │ │ │ ├── Contents.json │ │ │ ├── Inner │ │ │ │ ├── Contents.json │ │ │ │ ├── ski.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── smart-crop-4 (4) 1.png │ │ │ │ └── sofa.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── sofa.png │ │ │ ├── Video │ │ │ │ ├── Contents.json │ │ │ │ ├── instagram.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Group.svg │ │ │ │ ├── tiktok.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── tiktok-white-icon.svg │ │ │ │ └── youtube.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── Youtube_shorts_icon 1.svg │ │ │ ├── background_normalizing.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── background_normalizing.png │ │ │ ├── color_alternation.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── color_alternation.png │ │ │ ├── delivery-city.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── optimization_hero_gezokr.png │ │ │ ├── localization_branding.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── localization_branding.png │ │ │ └── smart_cropping.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Rectangle 3 (1).png │ │ ├── Upload │ │ │ ├── Contents.json │ │ │ ├── question_mark.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── ic_help_outline_24px.svg │ │ │ └── upload_missing.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── picturepile-4.png │ │ ├── Video │ │ │ ├── Contents.json │ │ │ └── TikTok │ │ │ │ ├── Contents.json │ │ │ │ ├── tiktok_bar_icon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Group 5.svg │ │ │ │ ├── tiktok_comments.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Group 2.svg │ │ │ │ ├── tiktok_discover.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Vector (3).svg │ │ │ │ ├── tiktok_home.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Vector (2).svg │ │ │ │ ├── tiktok_inbox.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Group 3.svg │ │ │ │ ├── tiktok_like.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Vector (4).svg │ │ │ │ ├── tiktok_more.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── icon_more.png │ │ │ │ ├── tiktok_music.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── music animation.png │ │ │ │ ├── tiktok_note.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Vector (1).svg │ │ │ │ ├── tiktok_share.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Vector (5).svg │ │ │ │ └── tiktok_social_icon.imageset │ │ │ │ ├── Avatar.svg │ │ │ │ └── Contents.json │ │ ├── Widgets │ │ │ ├── Contents.json │ │ │ └── house.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── Frame_871_ao5o4r_2_viaeyi.heic │ │ ├── back_arrow.imageset │ │ │ ├── Contents.json │ │ │ └── left _arrow.svg │ │ ├── car-speed-limiter.imageset │ │ │ ├── Contents.json │ │ │ └── car-speed-limiter 1.svg │ │ ├── cloudinary_logo.imageset │ │ │ ├── Contents.json │ │ │ └── Layer 1.svg │ │ ├── info_icon.imageset │ │ │ ├── Contents.json │ │ │ └── info_icon.svg │ │ ├── splash.imageset │ │ │ ├── Contents.json │ │ │ └── Image.png │ │ ├── splash_without_logo.imageset │ │ │ ├── Contents.json │ │ │ └── Splashwithoutlogo.jpg │ │ ├── upload.imageset │ │ │ ├── Contents.json │ │ │ └── upload-outline 1.svg │ │ ├── video.imageset │ │ │ ├── Contents.json │ │ │ └── Frame 12.svg │ │ └── widgets.imageset │ │ │ ├── Contents.json │ │ │ └── widgets-outline 1.svg │ ├── CldModel.xcdatamodeld │ │ └── CldModel.xcdatamodel │ │ │ └── contents │ ├── Cloudinary_Example-Bridging-Header.h │ ├── Colors.xcassets │ │ ├── Contents.json │ │ ├── gradient-first.colorset │ │ │ └── Contents.json │ │ ├── gradient-second.colorset │ │ │ └── Contents.json │ │ ├── primary.colorset │ │ │ └── Contents.json │ │ ├── secondary.colorset │ │ │ └── Contents.json │ │ ├── size_green.colorset │ │ │ └── Contents.json │ │ ├── size_red.colorset │ │ │ └── Contents.json │ │ ├── surface.colorset │ │ │ └── Contents.json │ │ └── text_not_selected.colorset │ │ │ └── Contents.json │ ├── Controllers │ │ ├── Base │ │ │ └── BaseViewController.swift │ │ ├── Inner Views │ │ │ ├── Transform │ │ │ │ ├── DeliveryViewController.swift │ │ │ │ ├── Optimization │ │ │ │ │ └── OptimizationViewController.swift │ │ │ │ ├── Transformation │ │ │ │ │ ├── DeliveryTransformCollectionController.swift │ │ │ │ │ ├── Reveal Image │ │ │ │ │ │ └── RevealImageController.swift │ │ │ │ │ ├── Smart Cropping │ │ │ │ │ │ └── SmartCroppingController.swift │ │ │ │ │ ├── TransformCollectionCell.swift │ │ │ │ │ ├── TransformCollectionController.swift │ │ │ │ │ ├── TransformViewController.swift │ │ │ │ │ └── TransformationCell.swift │ │ │ │ └── Use Cases │ │ │ │ │ ├── DeliveryUseCasesCollectionController.swift │ │ │ │ │ ├── Screens │ │ │ │ │ ├── ConditionalProductViewController.swift │ │ │ │ │ ├── IntegrateAIViewController.swift │ │ │ │ │ └── NormalizingProductAssetsViewController.swift │ │ │ │ │ ├── UseCaseCell.swift │ │ │ │ │ ├── UseCaseCollectionCell.swift │ │ │ │ │ ├── UseCasesCollectionController.swift │ │ │ │ │ └── UseCasesViewController.swift │ │ │ ├── Upload │ │ │ │ ├── InnerUploadFrame.swift │ │ │ │ ├── Single Upload │ │ │ │ │ ├── SingleUploadCell.swift │ │ │ │ │ ├── SingleUploadCollectionController.swift │ │ │ │ │ ├── SingleUploadCollectionLayout.swift │ │ │ │ │ ├── SingleUploadPreview.swift │ │ │ │ │ └── SingleUploadViewController.swift │ │ │ │ ├── Upload Does Not Exist │ │ │ │ │ └── UploadDoesNotExistController.swift │ │ │ │ ├── UploadChoiceController.swift │ │ │ │ ├── UploadNoCloudController.swift │ │ │ │ └── UploadViewController.swift │ │ │ └── Video │ │ │ │ ├── Video Feed │ │ │ │ └── VideoFeedCell.swift │ │ │ │ └── VideoFeedCollectionController.swift │ │ ├── MainViewController.swift │ │ ├── SplashViewController.swift │ │ ├── Video Feed │ │ │ ├── Controllers │ │ │ │ ├── MainPageController.swift │ │ │ │ ├── VideoFeedContainerController.swift │ │ │ │ ├── VideoFeedController.swift │ │ │ │ ├── VideoFeedViewController.swift │ │ │ │ ├── VideoSocialOverlaysController.swift │ │ │ │ └── VideoViewController.swift │ │ │ ├── Helpers │ │ │ │ └── VideoHelper.swift │ │ │ └── Resources │ │ │ │ └── video_links.plist │ │ └── Widgets │ │ │ ├── ImageWidgetViewController.swift │ │ │ ├── UploadWidgetViewController.swift │ │ │ └── WidgetsViewController.swift │ ├── Core Data │ │ ├── AssetItems+CoreDataClass.swift │ │ ├── AssetItems+CoreDataProperties.swift │ │ ├── AssetModel.swift │ │ ├── AssetModel.xcdatamodeld │ │ │ └── Model.xcdatamodel │ │ │ │ └── contents │ │ └── CoreDataHelper.swift │ ├── Custom Views │ │ ├── GradientView.swift │ │ ├── RevealImageView.swift │ │ ├── ToolBar │ │ │ ├── Item │ │ │ │ ├── ToolbarItem.swift │ │ │ │ └── ToolbarItem.xib │ │ │ ├── Toolbar.swift │ │ │ └── Toolbar.xib │ │ └── Upload Loading View │ │ │ ├── UploadLoadingView.swift │ │ │ └── UploadLoadingView.xib │ ├── Extensions │ │ └── Double+Extension.swift │ ├── GoogleService-Info.plist │ ├── Helpers │ │ ├── AnimationHelper.swift │ │ ├── Events │ │ │ ├── EventObject.swift │ │ │ ├── EventsHandler.swift │ │ │ ├── EventsProvider.swift │ │ │ └── FirebaseEventsHandler.swift │ │ └── ImageHelper.swift │ ├── Info.plist │ ├── SceneDelegate.swift │ ├── Utils │ │ ├── CloudinaryHelper.swift │ │ └── FileUtils.swift │ └── Views │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Inner Views │ │ ├── Base │ │ │ └── Base.storyboard │ │ ├── Transform │ │ │ ├── Delivery.storyboard │ │ │ ├── Optimization.storyboard │ │ │ ├── Use Cases │ │ │ │ ├── ConditionalProduct.storyboard │ │ │ │ ├── IntegrateAI.storyboard │ │ │ │ └── NormalizingProductAssets.storyboard │ │ │ └── UseCases.storyboard │ │ ├── Upload │ │ │ ├── InnerUploadFrame.xib │ │ │ ├── Upload.storyboard │ │ │ └── UploadNoCloud.storyboard │ │ ├── Video │ │ │ ├── Social │ │ │ │ └── VideoSocialOverlays.storyboard │ │ │ ├── Video.storyboard │ │ │ └── VideoFeed.storyboard │ │ └── Widgets │ │ │ ├── ImageWidget.storyboard │ │ │ ├── UploadWidget.storyboard │ │ │ └── Widgets.storyboard │ │ ├── Splash.storyboard │ │ ├── Transform │ │ ├── RevealImage.storyboard │ │ ├── SmartCropping.storyboard │ │ └── Transform.storyboard │ │ └── Upload │ │ ├── SingleUpload.storyboard │ │ ├── SingleUploadPreview.storyboard │ │ ├── UploadChoice.storyboard │ │ └── UploadDoesNotExist.storyboard ├── Podfile ├── README.md ├── Tests │ ├── BaseNetwork │ │ ├── BaseTestCase.swift │ │ ├── Core │ │ │ ├── AuthenticationTests.swift │ │ │ ├── CLDCloudinaryTests.m │ │ │ ├── CLDCloudinaryTests.swift │ │ │ ├── ParameterEncodingTests.swift │ │ │ ├── RequestTests.swift │ │ │ ├── ResponseTests.swift │ │ │ ├── ResultTests.swift │ │ │ ├── SessionDelegateTests.swift │ │ │ ├── SessionManagerTests.swift │ │ │ └── UploadTests.swift │ │ ├── Extensions │ │ │ ├── CLDNDataResponse+CloudinaryTests.swift │ │ │ ├── CLDNError+CloudinaryTests.swift │ │ │ ├── CLDNResult+CloudinaryTests.swift │ │ │ └── FileManager+CloudinaryTests.swift │ │ ├── Features │ │ │ ├── CacheTests.swift │ │ │ ├── MultipartFormDataTests.swift │ │ │ ├── ResponseSerializationTests.swift │ │ │ ├── URLProtocolTests.swift │ │ │ └── ValidationTests.swift │ │ ├── ObjcBaseTestCase.h │ │ ├── ObjcBaseTestCase.m │ │ └── Resources │ │ │ ├── Images │ │ │ ├── rainbow.jpg │ │ │ └── unicorn.png │ │ │ └── Responses │ │ │ ├── JSON │ │ │ ├── empty_data.json │ │ │ ├── invalid_data.json │ │ │ └── valid_data.json │ │ │ ├── Property List │ │ │ ├── empty.data │ │ │ ├── invalid.data │ │ │ └── valid.data │ │ │ └── String │ │ │ ├── empty_string.txt │ │ │ ├── utf32_string.txt │ │ │ └── utf8_string.txt │ ├── ConfigurationTests │ │ ├── CLDAnalyticsTests.swift │ │ ├── CLDConfigurationTests.m │ │ └── CLDConfigurationTests.swift │ ├── CryptoUtilsTests │ │ ├── CryptoUtilsTests.m │ │ └── CryptoUtilsTests.swift │ ├── FileUtilsTests.swift │ ├── GenerateUrlTests │ │ ├── UrlTests.m │ │ └── UrlTests.swift │ ├── Info.plist │ ├── NetworkTests │ │ ├── AccessibilityUploderTests │ │ │ ├── UploaderAccessibilityTests.m │ │ │ └── UploaderAccessibilityTests.swift │ │ ├── DownloaderAssetTests.swift │ │ ├── DownloaderTests.swift │ │ ├── ManagementApiTests.swift │ │ ├── NetworkBaseTests │ │ │ ├── NetworkBaseTest.swift │ │ │ ├── NetworkBaseTestObjc.h │ │ │ └── NetworkBaseTestObjc.m │ │ ├── NetworkTestUtils.swift │ │ └── UploaderTests │ │ │ ├── MockProvider │ │ │ └── BaseMockProvider.swift │ │ │ ├── OcrUploaderTests │ │ │ ├── ExplicitMockOcrTests.m │ │ │ ├── ExplicitMockOcrTests.swift │ │ │ ├── OcrMockProvider.swift │ │ │ ├── UploaderMockOcrTests.m │ │ │ ├── UploaderMockOcrTests.swift │ │ │ └── UploaderOcrTests.swift │ │ │ ├── PreprocessUploaderTests │ │ │ └── PreprocessUploaderTests.swift │ │ │ ├── QualityAnalysisUploaderTests │ │ │ ├── MockProviderQualityAnalysis.swift │ │ │ ├── ObjcQualityAnalysisExplicitResultParserTests.m │ │ │ ├── ObjcQualityAnalysisUploadResultParserTests.m │ │ │ ├── ObjcUploaderQualityAnalysisTests.m │ │ │ ├── QualityAnalysisExplicitResultParserTests.swift │ │ │ ├── QualityAnalysisUploadResultParserTests.swift │ │ │ └── UploaderQualityAnalysisTests.swift │ │ │ └── UploaderTests.swift │ ├── ParamTests │ │ └── UploadRequestParamsTests.swift │ ├── Preprocess │ │ ├── PreprocessTests.swift │ │ └── VideoPreprocessTests.swift │ ├── Resources │ │ ├── Docs │ │ │ ├── docx.docx │ │ │ └── pdf.pdf │ │ ├── Images │ │ │ ├── borderCollie.jpg │ │ │ ├── borderCollieCropped.jpg │ │ │ ├── borderCollieRotatedJpg.jpg │ │ │ ├── borderCollieRotatedJpgUnderIOS12.jpg │ │ │ ├── borderCollieRotatedPng.png │ │ │ ├── borderCollieRotatedPngUnderIOS12.png │ │ │ ├── logo.png │ │ │ └── textImage.jpg │ │ └── Videos │ │ │ ├── dog.mov │ │ │ ├── dog.mp4 │ │ │ └── dog2.mp4 │ ├── StringUtilsTest.swift │ ├── TestableCloudinary.swift │ ├── TransformationTests │ │ ├── CLDConditionExpressionTests │ │ │ ├── CLDConditionExpressionHelpersTests.swift │ │ │ ├── CLDConditionExpressionTests.m │ │ │ └── CLDConditionExpressionTests.swift │ │ ├── CLDExpressionTests │ │ │ ├── CLDExpressionTests.m │ │ │ └── CLDExpressionTests.swift │ │ ├── CLDTransformationTests │ │ │ ├── CLDTransformationBaselineTests.swift │ │ │ ├── CLDTransformationConditionsTests.swift │ │ │ ├── CLDTransformationExpressionsTests.swift │ │ │ ├── CLDTransformationTests.m │ │ │ ├── CLDTransformationTests.swift │ │ │ └── CLDTransformationVariablesTests.swift │ │ └── CLDVariableTests │ │ │ ├── CLDVariableTests.m │ │ │ └── CLDVariableTests.swift │ ├── UIExtensions │ │ ├── CLDVideoPlayerTests.swift │ │ ├── UIBaseTest.swift │ │ ├── UIButtonTests.swift │ │ ├── UIImageViewTests.swift │ │ └── Video Analytics │ │ │ ├── VideoEventsManagerTests.swift │ │ │ └── VideoEventsTests.swift │ └── UploadWidgetTests │ │ ├── UploadWidgetHelpersTests │ │ ├── UploaderWidgetAssetContainerTests.swift │ │ ├── UploaderWidgetConfigurationTests.m │ │ └── UploaderWidgetConfigurationTests.swift │ │ ├── UploadWidgetVideoTests │ │ ├── UploaderWidgetVideoControlsTests.swift │ │ ├── UploaderWidgetVideoDisplayLinkTests.swift │ │ ├── UploaderWidgetVideoPlayerTests.swift │ │ └── UploaderWidgetVideoViewTests.swift │ │ ├── UploaderWidgetEditTests │ │ └── UploaderWidgetEditViewControllerTests.swift │ │ ├── UploaderWidgetPreviewTests │ │ ├── UploaderWidgetCollectionCellTests.swift │ │ └── UploaderWidgetPreviewViewControllerTests.swift │ │ ├── UploaderWidgetTests │ │ ├── UploaderWidgetTests.m │ │ └── UploaderWidgetTests.swift │ │ ├── UploaderWidgetViewControllerTests │ │ └── UploaderWidgetViewControllerTests.swift │ │ └── WidgetBaseTest.swift └── WidgetUITests │ ├── Info.plist │ └── WidgetUITests.swift ├── LICENSE ├── Package.swift ├── Package@swift-5.3.swift ├── README.md ├── _Pods.xcodeproj └── tools └── get_test_cloud.sh /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Bug report for Cloudinary iOS SDK 11 | Before proceeding, please update to latest version and test if the issue persists 12 | 13 | ## Describe the bug in a sentence or two. 14 | … 15 | 16 | ## Issue Type (Can be multiple) 17 | [ ] Build - Can’t install or import the SDK 18 | [ ] Performance - Performance issues 19 | [ ] Behaviour - Functions aren’t working as expected (Such as generate URL) 20 | [ ] Documentation - Inconsistency between the docs and behaviour 21 | [ ] Other (Specify) 22 | 23 | ## Steps to reproduce 24 | … if applicable 25 | 26 | ## Error screenshots or Stack Trace (if applicable) 27 | … 28 | 29 | ## Build/Dependency management 30 | [ ] Cocoa-Pods 31 | [ ] Carthage 32 | [ ] Manual import 33 | [ ] Other (Specify) 34 | 35 | ## Is the issue reproducible only on a specific device? 36 | [ ] No 37 | [ ] Yes (specify model + iOS version) 38 | 39 | ## Versions and Libraries (fill in the version numbers) 40 | iOS Cloudinary SDK version - 0.0.0 41 | OSX (on the dev environment) - 0.0.0 42 | XCode - 0.0.0 43 | Swift - 0.0.0 44 | Target iOS - 0.0.0 45 | 46 | Repository 47 | If possible, please provide a link to a reproducible repository that showcases the problem 48 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Feature request for Cloudinary iOS SDK 11 | …(If your feature is for other SDKs, please request them there) 12 | 13 | ## Explain your use case 14 | … (A high level explanation of why you need this feature) 15 | 16 | ## Describe the problem you’re trying to solve 17 | … (A more technical view of what you’d like to accomplish, and how this feature will help you achieve it) 18 | 19 | ## Do you have a proposed solution? 20 | … (yes, no? Please elaborate if needed) 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Brief Summary of Changes 2 | 3 | 4 | #### What does this PR address? 5 | - [ ] GitHub issue (Add reference - #XX) 6 | - [ ] Refactoring 7 | - [ ] New feature 8 | - [ ] Bug fix 9 | - [ ] Adds more tests 10 | 11 | #### Are tests included? 12 | - [ ] Yes 13 | - [ ] No 14 | 15 | #### Reviewer, please note: 16 | 23 | 24 | #### Checklist: 25 | 26 | 27 | - [ ] My code follows the code style of this project. 28 | - [ ] My change requires a change to the documentation. 29 | - [ ] I ran the full test suite before pushing the changes and all the tests pass. 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | *.DS_Store 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData/ 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata/ 21 | 22 | ## Other 23 | *.moved-aside 24 | *.xcuserstate 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | *.dSYM.zip 30 | *.dSYM 31 | 32 | ## Playgrounds 33 | timeline.xctimeline 34 | playground.xcworkspace 35 | 36 | # Swift Package Manager 37 | # 38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 39 | # Packages/ 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | # Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | Example/Carthage/Checkouts 54 | 55 | Example/Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots 67 | fastlane/test_output 68 | iOSInjectionProject/ 69 | 70 | Cloudinary/Frameworks/CLDCrypto 71 | 72 | # Samples 73 | AppDelegate+config.swift 74 | Example/Pods/ 75 | Example/Podfile.lock 76 | Example/Cloudinary.xcworkspace/ 77 | 78 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | os: osx 3 | before_script: > 4 | export CLOUDINARY_URL=$(bash tools/get_test_cloud.sh); 5 | echo cloud_name: "$(echo $CLOUDINARY_URL | cut -d'@' -f2)" 6 | notifications: 7 | email: 8 | recipients: 9 | - sdk_developers@cloudinary.com 10 | jobs: 11 | - osx_image: xcode12 12 | xcode_workspace: Example/Cloudinary.xcworkspace 13 | xcode_scheme: travis_public_scheme 14 | podfile: Example/Podfile 15 | install: pod install --project-directory=Example 16 | env: CLOUDINARY_URL=$CLOUDINARY_URL 17 | xcode_destination: platform=iOS Simulator,OS=13.0,name=iPhone 8 18 | - osx_image: xcode12 19 | xcode_workspace: Example/Cloudinary.xcworkspace 20 | xcode_scheme: travis_public_scheme 21 | podfile: Example/Podfile 22 | install: pod install --project-directory=Example 23 | env: CLOUDINARY_URL=$CLOUDINARY_URL 24 | xcode_destination: platform=iOS Simulator,OS=14.0,name=iPhone 8 25 | - osx_image: xcode13.2 26 | xcode_workspace: Example/Cloudinary.xcworkspace 27 | xcode_scheme: travis_public_scheme 28 | podfile: Example/Podfile 29 | install: pod install --project-directory=Example 30 | env: CLOUDINARY_URL=$CLOUDINARY_URL 31 | xcode_destination: platform=iOS Simulator,OS=15.2,name=iPhone 8 32 | -------------------------------------------------------------------------------- /Cloudinary.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint Cloudinary.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'Cloudinary' 11 | s.version = '5.1.0' 12 | s.summary = "Cloudinary is a cloud service that offers a solution to a web application's entire image management pipeline." 13 | 14 | s.description = <<-DESC 15 | Easily upload images to the cloud. Automatically perform smart image resizing, cropping and conversion without installing any complex software. 16 | Integrate Facebook or Twitter profile image extraction in a snap, in any dimension and style to match your website’s graphics requirements. 17 | Images are seamlessly delivered through a fast CDN, and much much more. 18 | Cloudinary offers comprehensive APIs and administration capabilities and is easy to integrate with any web application, existing or new. 19 | Cloudinary provides URL and HTTP based APIs that can be easily integrated with any Web development framework. 20 | DESC 21 | 22 | s.homepage = 'http://cloudinary.com' 23 | s.license = { :type => 'MIT', :file => 'LICENSE' } 24 | s.author = { "Cloudinary" => "info@cloudinary.com" } 25 | s.source = { :git => "https://github.com/cloudinary/cloudinary_ios.git", :tag => s.version.to_s } 26 | 27 | s.swift_version = '5.0' 28 | s.ios.deployment_target = '9.0' 29 | s.frameworks = 'UIKit', 'Foundation' 30 | 31 | s.default_subspec = 'ios' 32 | 33 | s.subspec 'ios' do |spec| 34 | 35 | spec.platform = :ios 36 | spec.source_files = 'Cloudinary/Classes/**/*.{swift,h}' 37 | spec.resource_bundles = { 'Cloudinary' => ['Cloudinary/Classes/Core/Network/PrivacyInfo.xcprivacy'] } 38 | 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /Cloudinary.xcodeproj/Cloudinary_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | FMWK 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Cloudinary.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /Cloudinary.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Cloudinary.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | -------------------------------------------------------------------------------- /Cloudinary.xcodeproj/xcshareddata/xcschemes/Cloudinary-Package.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Cloudinary/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Cloudinary/Assets/.gitkeep -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/BaseNetwork/DispatchQueue+Cloudinary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DispatchQueue+Cloudinary.swift 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | // 23 | 24 | import Dispatch 25 | import Foundation 26 | 27 | extension DispatchQueue { 28 | static var CLDNUserInteractive: DispatchQueue { return DispatchQueue.global(qos: .userInteractive) } 29 | static var CLDNUserInitiated: DispatchQueue { return DispatchQueue.global(qos: .userInitiated) } 30 | static var CLDNUtility: DispatchQueue { return DispatchQueue.global(qos: .utility) } 31 | static var CLDNBackground: DispatchQueue { return DispatchQueue.global(qos: .background) } 32 | 33 | func CLDN_after(_ delay: TimeInterval, execute closure: @escaping () -> Void) { 34 | asyncAfter(deadline: .now() + delay, execute: closure) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/CLDCompatibility.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Amir on 05/11/2017. 3 | // Copyright (c) 2017 Cloudinary. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | 8 | #if swift(>=4.0) 9 | internal extension NSTextCheckingResult { 10 | func rangeAt(_ idx:Int) -> NSRange { 11 | return range(at: idx) 12 | } 13 | } 14 | #endif 15 | 16 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/CLDEagerTransformation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Nitzan Jaitman on 09/05/2018. 3 | // Copyright (c) 2018 Cloudinary. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | 8 | open class CLDEagerTransformation: CLDTransformation { 9 | /** 10 | Set the format for the eager transformation 11 | */ 12 | fileprivate var eagerFormat: String? 13 | 14 | open func setFormat(_ format: String?) -> Self{ 15 | self.eagerFormat = format 16 | return self; 17 | } 18 | 19 | override func getStringRepresentationFromParams(_ params: [String: String]) -> String? { 20 | // return the original transformation string with a /format if set. 21 | var result = "" 22 | if let baseTransformation = super.getStringRepresentationFromParams(params) { 23 | result += baseTransformation 24 | } 25 | 26 | if let format = eagerFormat { 27 | result += "/\(format)" 28 | } 29 | 30 | return result 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Cloudinary.h: -------------------------------------------------------------------------------- 1 | // 2 | // Cloudinary.h 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | //! Project version number for Cloudinary. 28 | FOUNDATION_EXPORT double CloudinaryVersionNumber; 29 | 30 | //! Project version string for Cloudinary. 31 | FOUNDATION_EXPORT const unsigned char CloudinaryVersionString[]; 32 | 33 | // In this header, you should import all the public headers of your framework using statements like #import 34 | 35 | 36 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Downloader/CLDDownloader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDDownloader.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | /** 28 | The CLDDownloader class is used to asynchronously fetch images either from the image cache if they exist or download them from a remote source. 29 | */ 30 | @objcMembers open class CLDDownloader: CLDBaseNetworkObject { 31 | 32 | // MARK: - Init 33 | internal fileprivate(set) var downloadCoordinator: CLDDownloadCoordinator! 34 | 35 | fileprivate override init() { 36 | super.init() 37 | } 38 | 39 | internal init(downloadCoordinator: CLDDownloadCoordinator) { 40 | 41 | self.downloadCoordinator = downloadCoordinator 42 | super.init(networkCoordinator: downloadCoordinator) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/CLDBaseNetworkObject.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDBaseNetworkObject.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDBaseNetworkObject: NSObject { 28 | 29 | 30 | internal fileprivate(set) var networkCoordinator: CLDNetworkCoordinator! 31 | 32 | internal override init() { 33 | super.init() 34 | } 35 | 36 | internal init(networkCoordinator: CLDNetworkCoordinator) { 37 | self.networkCoordinator = networkCoordinator 38 | super.init() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Layers/CLDFetchLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDFetchLayer.swift 3 | // Cloudinary 4 | // 5 | // Created by Nitzan Jaitman on 19/02/2019. 6 | // Copyright © 2019 Cloudinary. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @objcMembers open class CLDFetchLayer: CLDLayer { 12 | 13 | // MARK: - Init 14 | 15 | /** 16 | Initialize a CLDFetchLayer instance. 17 | 18 | - parameter url: The url of the remote resource to fetch 19 | 20 | - returns: The new CLDFetchLayer instance. 21 | */ 22 | public init(url: String) { 23 | super.init() 24 | setPublicId(publicId: url.cldBase64UrlEncode()) 25 | resourceType = String(describing: LayerResourceType.fetch) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Layers/CLDSubtitlesLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDSubtitlesLayer.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDSubtitlesLayer: CLDTextLayer { 28 | 29 | // MARK: - Init 30 | 31 | /** 32 | Initialize a CLDLayer instance. 33 | 34 | -returns: The new CLDLayer instance. 35 | */ 36 | public override init() { 37 | super.init() 38 | resourceType = String(describing: LayerResourceType.subtitles) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/CLDBaseResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDBaseResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDBaseResult: NSObject { 28 | 29 | open fileprivate(set) var resultJson: [String : AnyObject] 30 | 31 | 32 | // MARK: - Init 33 | 34 | internal init(json: [String : AnyObject]) { 35 | resultJson = json 36 | } 37 | 38 | // MARK: - Private Helpers 39 | 40 | internal func getParam(_ param: CommonResultKeys) -> AnyObject? { 41 | return resultJson[String(describing: param)] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDDetection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDDetection.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDDetection: CLDBaseResult { 28 | 29 | open var rekognitionFace: CLDRekognitionFace? { 30 | guard let rekognitionFace = getParam(.rekognitionFace) as? [String : AnyObject] else { 31 | return nil 32 | } 33 | return CLDRekognitionFace(json: rekognitionFace) 34 | } 35 | 36 | // MARK: - Private Helpers 37 | 38 | fileprivate func getParam(_ param: CLDDetectionKey) -> AnyObject? { 39 | return resultJson[String(describing: param)] 40 | } 41 | 42 | fileprivate enum CLDDetectionKey: CustomStringConvertible { 43 | case rekognitionFace 44 | 45 | var description: String { 46 | switch self { 47 | case .rekognitionFace: return "rekognition_face" 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDInfo.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDInfo: CLDBaseResult { 28 | 29 | open var detection: CLDDetection? { 30 | guard let detection = getParam(.detection) as? [String : AnyObject] else { 31 | return nil 32 | } 33 | return CLDDetection(json: detection) 34 | } 35 | 36 | open var ocr: CLDOcrResult? { 37 | guard let ocr = getParam(.ocr) as? [String : AnyObject] else { 38 | return nil 39 | } 40 | return CLDOcrResult(json: ocr) 41 | } 42 | 43 | // MARK: - Private Helpers 44 | 45 | fileprivate func getParam(_ param: CLDInfoKey) -> AnyObject? { 46 | return resultJson[String(describing: param)] 47 | } 48 | 49 | fileprivate enum CLDInfoKey: CustomStringConvertible { 50 | case detection, ocr 51 | 52 | var description: String { 53 | switch self { 54 | case .detection: return "detection" 55 | case .ocr : return "ocr" 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDOcr/CLDAdvOcrResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDAdvOcrResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDAdvOcrResult: CLDBaseResult { 28 | 29 | open var status: String? { 30 | guard let status = getParam(.status) as? String else { return nil } 31 | 32 | return status 33 | } 34 | open var data: [CLDOcrDataResult]? { 35 | guard let data = getParam(.data) as? [[String : AnyObject]] else { return nil } 36 | 37 | return data.compactMap{ CLDOcrDataResult(json: $0) } 38 | } 39 | 40 | // MARK: - Private Helpers 41 | fileprivate func getParam(_ param: CLDAdvOcrResultKey) -> AnyObject? { 42 | return resultJson[String(describing: param)] 43 | } 44 | 45 | fileprivate enum CLDAdvOcrResultKey: CustomStringConvertible { 46 | case status, data 47 | 48 | var description: String { 49 | switch self { 50 | case .status: return "status" 51 | case .data : return "data" 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDOcr/CLDOcrBoundindBlockResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDOcrBoundindBlockResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | import CoreGraphics 27 | 28 | @objcMembers open class CLDOcrBoundindBlockResult: CLDBaseResult { 29 | 30 | open var vertices: [CGPoint]? { 31 | guard let vertices = getParam(.vertices) as? [[String : AnyObject]] else { return nil} 32 | 33 | return vertices.compactMap{ 34 | if let x = $0["x"] as? NSNumber, let y = $0["y"] as? NSNumber { 35 | return CGPoint(x: x.intValue, y: y.intValue) 36 | } 37 | else { 38 | return nil 39 | } 40 | } 41 | } 42 | 43 | // MARK: - Private Helpers 44 | fileprivate func getParam(_ param: CLDOcrBoundindBlockResultKey) -> AnyObject? { 45 | return resultJson[String(describing: param)] 46 | } 47 | 48 | fileprivate enum CLDOcrBoundindBlockResultKey: CustomStringConvertible { 49 | case vertices 50 | 51 | var description: String { 52 | switch self { 53 | case .vertices : return "vertices" 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDOcr/CLDOcrDetectedLanguagesResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDOcrDetectedLanguagesResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDOcrDetectedLanguagesResult: CLDBaseResult { 28 | 29 | open var languageCode: String? { 30 | guard let languageCode = getParam(.languageCode) as? String else { return nil } 31 | 32 | return languageCode 33 | } 34 | open var confidence: Int? { 35 | guard let confidence = getParam(.confidence) as? Int else { return nil } 36 | 37 | return confidence 38 | } 39 | 40 | // MARK: - Private Helpers 41 | fileprivate func getParam(_ param: CLDOcrDetectedLanguagesResultKey) -> AnyObject? { 42 | return resultJson[String(describing: param)] 43 | } 44 | 45 | fileprivate enum CLDOcrDetectedLanguagesResultKey: CustomStringConvertible { 46 | case languageCode, confidence 47 | 48 | var description: String { 49 | switch self { 50 | case .languageCode: return "languageCode" 51 | case .confidence : return "confidence" 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDOcr/CLDOcrFullTextAnnotationResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDOcrFullTextAnnotationResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDOcrFullTextAnnotationResult: CLDBaseResult { 28 | 29 | open var pages: [CLDOcrPageResult]? { 30 | guard let pages = getParam(.pages) as? [[String : AnyObject]] else { return nil } 31 | 32 | return pages.compactMap({ CLDOcrPageResult(json: $0) }) 33 | } 34 | open var text: String? { 35 | guard let text = getParam(.text) as? String else { return nil } 36 | 37 | return text 38 | } 39 | 40 | // MARK: - Private Helpers 41 | fileprivate func getParam(_ param: CLDOcrFullTextAnnotationResultKey) -> AnyObject? { 42 | return resultJson[String(describing: param)] 43 | } 44 | 45 | fileprivate enum CLDOcrFullTextAnnotationResultKey: CustomStringConvertible { 46 | case pages, text 47 | 48 | var description: String { 49 | switch self { 50 | case .pages: return "pages" 51 | case .text : return "text" 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDOcr/CLDOcrPropertyResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDOcrPropertyResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDOcrPropertyResult: CLDBaseResult { 28 | 29 | open var detectedLanguages: [CLDOcrDetectedLanguagesResult]? { 30 | guard let detectedLanguages = getParam(.detectedLanguages) as? [[String : AnyObject]] else { return nil } 31 | 32 | return detectedLanguages.compactMap({ CLDOcrDetectedLanguagesResult(json: $0) }) 33 | } 34 | 35 | 36 | // MARK: - Private Helpers 37 | fileprivate func getParam(_ param: CLDOcrPropertyResultKey) -> AnyObject? { 38 | return resultJson[String(describing: param)] 39 | } 40 | 41 | fileprivate enum CLDOcrPropertyResultKey: CustomStringConvertible { 42 | case detectedLanguages 43 | 44 | var description: String { 45 | switch self { 46 | case .detectedLanguages: return "detectedLanguages" 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDOcr/CLDOcrResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDOcrResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDOcrResult: CLDBaseResult { 28 | 29 | open var advOcr: CLDAdvOcrResult? { 30 | guard let advOcr = getParam(.advOcr) as? [String : AnyObject] else { return nil } 31 | 32 | return CLDAdvOcrResult(json: advOcr) 33 | } 34 | 35 | // MARK: - Private Helpers 36 | fileprivate func getParam(_ param: CLDOcrResultKey) -> AnyObject? { 37 | return resultJson[String(describing: param)] 38 | } 39 | 40 | fileprivate enum CLDOcrResultKey: CustomStringConvertible { 41 | case advOcr 42 | 43 | var description: String { 44 | switch self { 45 | case .advOcr: return "adv_ocr" 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/Helpers/Results/Helpers/CLDRekognitionFace.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDRekognitionFace.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDRekognitionFace: CLDBaseResult { 28 | 29 | open var status: String? { 30 | return getParam(.status) as? String 31 | } 32 | 33 | open var faces: [CLDFace]? { 34 | guard let facesArr = getParam(.faces) as? [[String : AnyObject]] else { 35 | return nil 36 | } 37 | var faces: [CLDFace] = [] 38 | for face in facesArr { 39 | faces.append(CLDFace(json: face)) 40 | } 41 | return faces 42 | } 43 | 44 | // MARK: - Private Helpers 45 | 46 | fileprivate func getParam(_ param: CLDRekognitionFaceKey) -> AnyObject? { 47 | return resultJson[String(describing: param)] 48 | } 49 | 50 | fileprivate enum CLDRekognitionFaceKey: CustomStringConvertible { 51 | case status, facesData 52 | 53 | var description: String { 54 | switch self { 55 | case .status: return "status" 56 | case .facesData: return "data" 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/ManagementApi/Results/CLDDeleteResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDDeleteResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDDeleteResult: CLDBaseResult { 28 | 29 | // MARK: - Getters 30 | 31 | open var result: String? { 32 | return getParam(.result) as? String 33 | } 34 | 35 | // MARK: - Private Helpers 36 | 37 | fileprivate func getParam(_ param: DeleteResultKey) -> AnyObject? { 38 | return resultJson[String(describing: param)] 39 | } 40 | 41 | fileprivate enum DeleteResultKey: CustomStringConvertible { 42 | case result 43 | 44 | var description: String { 45 | switch self { 46 | case .result: return "result" 47 | } 48 | } 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/ManagementApi/Results/CLDExplicitResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDExplicitResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objc open class CLDExplicitResult: CLDUploadResult { 28 | } 29 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/ManagementApi/Results/CLDExplodeResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDExplodeResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDExplodeResult: CLDBaseResult { 28 | 29 | // MARK: - Getters 30 | 31 | open var status: String? { 32 | return getParam(.status) as? String 33 | } 34 | 35 | open var batchId: String? { 36 | return getParam(.batchId) as? String 37 | } 38 | 39 | 40 | // MARK: - Private Helpers 41 | 42 | fileprivate func getParam(_ param: ExplodeResultKey) -> AnyObject? { 43 | return resultJson[String(describing: param)] 44 | } 45 | 46 | fileprivate enum ExplodeResultKey: CustomStringConvertible { 47 | case status, batchId 48 | 49 | var description: String { 50 | switch self { 51 | case .status: return "status" 52 | case .batchId: return "batch_id" 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/ManagementApi/Results/CLDMultiResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDMultiResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDMultiResult: CLDBaseResult { 28 | 29 | 30 | // MARK: - Getters 31 | 32 | open var url: String? { 33 | return getParam(.url) as? String 34 | } 35 | 36 | open var secureUrl: String? { 37 | return getParam(.secureUrl) as? String 38 | } 39 | 40 | open var publicId: String? { 41 | return getParam(.publicId) as? String 42 | } 43 | 44 | open var version: String? { 45 | guard let version = getParam(.version) else { 46 | return nil 47 | } 48 | return String(describing: version) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/ManagementApi/Results/CLDTagResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDTagResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDTagResult: CLDBaseResult { 28 | 29 | 30 | // MARK: - Getters 31 | 32 | open var publicIds: [String]? { 33 | return getParam(.publicIds) as? [String] 34 | } 35 | 36 | // MARK: - Private Helpers 37 | 38 | fileprivate func getParam(_ param: TagResultKey) -> AnyObject? { 39 | return resultJson[String(describing: param)] 40 | } 41 | 42 | fileprivate enum TagResultKey: CustomStringConvertible { 43 | case publicIds 44 | 45 | var description: String { 46 | switch self { 47 | case .publicIds: return "public_ids" 48 | } 49 | } 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/ManagementApi/Results/CLDTextResult.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDTextResult.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | @objcMembers open class CLDTextResult: CLDBaseResult { 28 | 29 | 30 | // MARK: - Getters 31 | 32 | open var width: Int? { 33 | return getParam(.width) as? Int 34 | } 35 | 36 | open var height: Int? { 37 | return getParam(.height) as? Int 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/UploadWidget/CropView/CLDCropScrollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDCropScrollView.swift 3 | // ProjectCLDWidgetEditViewController 4 | // 5 | // Created by Arkadi Yoskovitz on 8/17/20. 6 | // Copyright © 2020 Gini-Apps LTD. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | public typealias CLDTouchHandler = () -> Void 11 | 12 | /* 13 | Subclassing UIScrollView was necessary in order to directly capture 14 | touch events that weren't otherwise accessible via UIGestureRecognizer objects. 15 | */ 16 | @objc 17 | @objcMembers 18 | public class CLDCropScrollView : UIScrollView { 19 | 20 | public var touchesBegan :CLDTouchHandler? 21 | public var touchesCancelled:CLDTouchHandler? 22 | public var touchesEnded :CLDTouchHandler? 23 | 24 | override init(frame: CGRect) { 25 | super.init(frame: frame) 26 | configureInitialState() 27 | } 28 | 29 | required init?(coder aDecoder: NSCoder) { 30 | super.init(coder: aDecoder) 31 | configureInitialState() 32 | } 33 | 34 | private func configureInitialState() { 35 | 36 | self.autoresizingMask = [.flexibleHeight , .flexibleWidth] 37 | self.alwaysBounceHorizontal = true 38 | self.alwaysBounceVertical = true 39 | self.showsHorizontalScrollIndicator = false 40 | self.showsVerticalScrollIndicator = false 41 | } 42 | 43 | public override func touchesBegan(_ touches: Set, with event: UIEvent?) { 44 | if let handler = touchesBegan { 45 | handler() 46 | } 47 | super.touchesBegan(touches, with: event) 48 | } 49 | 50 | public override func touchesEnded(_ touches: Set, with event: UIEvent?) { 51 | if let handler = touchesEnded { 52 | handler() 53 | } 54 | super.touchesEnded(touches, with: event) 55 | } 56 | 57 | public override func touchesCancelled(_ touches: Set, with event: UIEvent?) { 58 | if let handler = touchesEnded { 59 | handler() 60 | } 61 | super.touchesCancelled(touches, with: event) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/UploadWidget/WidgetElements/CLDWidgetPreviewCollectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDWidgetPreviewCollectionCell.swift 3 | // 4 | // Copyright (c) 2020 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import UIKit 26 | 27 | class CLDWidgetPreviewCollectionCell: UICollectionViewCell { 28 | 29 | var imageView: UIImageView! 30 | 31 | // MARK: - init 32 | override init(frame: CGRect) { 33 | super.init(frame: frame) 34 | 35 | initialize() 36 | } 37 | 38 | required init?(coder: NSCoder) { 39 | fatalError("init(coder:) has not been implemented") 40 | } 41 | 42 | // MARK: - private methods 43 | private func initialize() { 44 | self.imageView = UIImageView(frame: self.contentView.bounds) 45 | addSubview(imageView) 46 | addImageViewProperties() 47 | } 48 | 49 | private func addImageViewProperties() { 50 | imageView.contentMode = .scaleAspectFill 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/UploadWidget/WidgetVideo/CLDVideoControlsState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDVideoControlsState.swift 3 | // 4 | // Copyright (c) 2020 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | protocol CLDVideoControlsState: AnyObject { 28 | 29 | var controlsView: CLDVideoControlsView { get set } 30 | 31 | init(controlsView: CLDVideoControlsView) 32 | 33 | func playPausePressed() 34 | func backgroundPressed() 35 | func timerFinished() 36 | func videoEnded() 37 | } 38 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/UploadWidget/WidgetVideo/CLDVideoHiddenAndPausedState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDVideoHiddenAndPausedState.swift 3 | // 4 | // Copyright (c) 2020 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | class CLDVideoHiddenAndPausedState: NSObject, CLDVideoControlsState { 28 | 29 | var controlsView: CLDVideoControlsView 30 | 31 | required init(controlsView: CLDVideoControlsView) { 32 | 33 | self.controlsView = controlsView 34 | super.init() 35 | } 36 | 37 | func playPausePressed() { 38 | print("playPausePressed shouldn't be called in CLDVideoHiddenAndPausedState") 39 | } 40 | 41 | func backgroundPressed() { 42 | 43 | controlsView.setNewState(newState: controlsView.shownAndPausedState) 44 | controlsView.stopTimer() 45 | 46 | controlsView.showControls() 47 | } 48 | 49 | func timerFinished() { 50 | print("timerFinished shouldn't be called in CLDVideoHiddenAndPausedState") 51 | } 52 | 53 | func videoEnded() { 54 | print("videoEnded shouldn't be called in CLDVideoHiddenAndPausedState") 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/UploadWidget/WidgetVideo/CLDVideoPlayerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDVideoPlayerView.swift 3 | // 4 | // Copyright (c) 2020 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import UIKit 26 | import AVKit 27 | 28 | class CLDVideoPlayerView: UIView { 29 | 30 | override class var layerClass: AnyClass { 31 | return AVPlayerLayer.self 32 | } 33 | 34 | var player : AVPlayer? { 35 | get { 36 | return playerLayer?.player 37 | } 38 | set { 39 | playerLayer?.player = newValue 40 | } 41 | } 42 | 43 | weak var playerLayer : AVPlayerLayer? { 44 | guard let layer = layer as? AVPlayerLayer else { return nil } 45 | return layer as AVPlayerLayer 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Features/UploadWidget/WidgetVideo/CLDVideoShownAndPausedState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDVideoShownAndPausedState.swift 3 | // 4 | // Copyright (c) 2020 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | class CLDVideoShownAndPausedState: NSObject, CLDVideoControlsState { 28 | 29 | var controlsView: CLDVideoControlsView 30 | 31 | required init(controlsView: CLDVideoControlsView) { 32 | 33 | self.controlsView = controlsView 34 | super.init() 35 | } 36 | 37 | func playPausePressed() { 38 | 39 | controlsView.playVideo() 40 | 41 | controlsView.setNewState(newState: controlsView.shownAndPlayingState) 42 | } 43 | 44 | func backgroundPressed() { 45 | 46 | controlsView.setNewState(newState: controlsView.hiddenAndPausedState) 47 | 48 | controlsView.hideControls() 49 | } 50 | 51 | func timerFinished() { 52 | print("timerFinished shouldn't be called in CLDVideoShownAndPausedState") 53 | } 54 | 55 | func videoEnded() { 56 | print("videoEnded shouldn't be called in CLDVideoShownAndPausedState") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Network/NetworkRequest/CLDErrorRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDRequestError.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | 25 | import Foundation 26 | 27 | /// Represents a failure to create the request 28 | internal class CLDRequestError: CLDFetchImageRequest { 29 | 30 | var error: Error 31 | 32 | // MARK: - Init 33 | 34 | init(error: Error) { 35 | self.error = error 36 | } 37 | 38 | // MARK: - CLDNetworkRequest 39 | func resume() { 40 | } 41 | 42 | func suspend() { 43 | } 44 | 45 | func cancel() { 46 | } 47 | 48 | // MARK: - CLDNetworkDataRequest 49 | 50 | func progress(_ progress: ((Progress) -> Void)?) -> CLDNetworkDataRequest { 51 | return self 52 | } 53 | 54 | 55 | func response(_ completionHandler: ((_ response: Any?, _ error: NSError?) -> ())?) -> CLDNetworkRequest { 56 | completionHandler?(nil, error as NSError?) 57 | return self 58 | } 59 | 60 | // MARK: - CLDFetchImageRequest 61 | 62 | func responseImage(_ completionHandler: CLDCompletionHandler?) -> CLDFetchImageRequest { 63 | completionHandler?(nil, error as NSError?) 64 | return self 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Network/NetworkRequest/CLDGenericNetworkRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDGenericNetworkRequest.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | internal class CLDGenericNetworkRequest: NSObject, CLDNetworkRequest { 28 | 29 | internal let request: T 30 | 31 | // MARK: - Init 32 | 33 | internal init(request: T) { 34 | self.request = request 35 | } 36 | 37 | //MARK: - State 38 | 39 | /** 40 | Resume the current request. 41 | */ 42 | func resume() { 43 | request.resume() 44 | } 45 | 46 | /** 47 | Suspend the current request. 48 | */ 49 | func suspend() { 50 | request.suspend() 51 | } 52 | 53 | /** 54 | Cancel the current request. 55 | */ 56 | func cancel() { 57 | request.cancel() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Network/NetworkRequest/CLDNetworkUploadRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDNetworkUploadRequest.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | internal class CLDNetworkUploadRequest: CLDNetworkDataRequestImpl { 28 | 29 | override func progress(_ progress: ((Progress) -> Void)?) -> CLDNetworkDataRequest { 30 | 31 | if let progress = progress{ 32 | request.uploadProgress(closure: progress) 33 | } 34 | 35 | return self 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Network/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPITypeReasons 9 | 10 | 0A2A.1 11 | 12 | NSPrivacyAccessedAPIType 13 | NSPrivacyAccessedAPICategoryFileTimestamp 14 | 15 | 16 | NSPrivacyCollectedDataTypes 17 | 18 | 19 | NSPrivacyCollectedDataTypePurposes 20 | 21 | NSPrivacyCollectedDataTypePurposeAppFunctionality 22 | 23 | NSPrivacyCollectedDataType 24 | NSPrivacyCollectedDataTypeAudioData 25 | NSPrivacyCollectedDataTypeTracking 26 | 27 | NSPrivacyCollectedDataTypeLinked 28 | 29 | 30 | 31 | NSPrivacyCollectedDataTypePurposes 32 | 33 | NSPrivacyCollectedDataTypePurposeAppFunctionality 34 | 35 | NSPrivacyCollectedDataType 36 | NSPrivacyCollectedDataTypeOtherUserContent 37 | NSPrivacyCollectedDataTypeTracking 38 | 39 | NSPrivacyCollectedDataTypeLinked 40 | 41 | 42 | 43 | NSPrivacyCollectedDataTypePurposes 44 | 45 | NSPrivacyCollectedDataTypePurposeAnalytics 46 | NSPrivacyCollectedDataTypePurposeAppFunctionality 47 | 48 | NSPrivacyCollectedDataTypeTracking 49 | 50 | NSPrivacyCollectedDataTypeLinked 51 | 52 | NSPrivacyCollectedDataType 53 | NSPrivacyCollectedDataTypePhotosorVideos 54 | 55 | 56 | NSPrivacyTrackingDomains 57 | 58 | NSPrivacyTracking 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Utils/CLDBuildParamsUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDBuildParamsUtils.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | 28 | // MARK: - Build String Params 29 | 30 | internal func buildCoordinatesString(_ coordinates: [CLDCoordinate]) -> String { 31 | return coordinates.map{$0.description}.joined(separator: "|") 32 | } 33 | 34 | internal func buildEagerString(_ eager: [CLDTransformation]) -> String { 35 | return eager.map {$0.asString() ?? ""} 36 | .filter {!$0.isEmpty} 37 | .joined(separator: "|") 38 | } 39 | 40 | internal func buildContextString(_ context: [String : String]) -> String { 41 | return context.map{"\($0)=\(encodeContextValue($1))"}.joined(separator: "|") 42 | } 43 | 44 | internal func encodeContextValue(_ value: String) -> String { 45 | return value.replacingOccurrences(of: "|", with: "\\|").replacingOccurrences(of: "=", with: "\\=") 46 | } 47 | 48 | internal func buildHeadersString(_ headers: [String : String]) -> String { 49 | return headers.map{"\($0): \($1)\\n"}.joined(separator: "") 50 | } 51 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Utils/CLDDictionaryUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDDictionaryUtils.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | internal extension Dictionary { 28 | mutating func cldMerge(_ otherDictionary: Dictionary?) { 29 | guard let otherDictionary = otherDictionary else { 30 | return 31 | } 32 | for (key,value) in otherDictionary { 33 | self.updateValue(value, forKey:key) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Cloudinary/Classes/Core/Utils/CLDImageUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDImageUtils.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | import UIKit 27 | 28 | private let lock = NSLock() 29 | 30 | internal extension Data { 31 | func cldToUIImageThreadSafe() -> UIImage? { 32 | lock.lock() 33 | let image = UIImage(data: self) 34 | lock.unlock() 35 | return image 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Cloudinary/Classes/ios/Extensions/CLDTransformation+Ios.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLDTransformation+Ios.swift 3 | // Cloudinary 4 | // 5 | // Created on 23/02/2020. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | extension CLDTransformation 12 | { 13 | /** 14 | Deliver the image in the correct device pixel ratio, according to the used device. 15 | 16 | - returns: The same instance of CLDTransformation. 17 | */ 18 | @discardableResult 19 | open func setDprAuto() -> Self { 20 | let scale = Float(UIScreen.main.scale) 21 | return setDpr(scale) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Cloudinary/Classes/ios/Uploader/CLDImagePreprocessChain.swift: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // CLDImagePreprocessChain.swift 4 | // 5 | // Copyright (c) 2017 Cloudinary (http://cloudinary.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | import UIKit 28 | 29 | /** 30 | The CLDImagePreprocessChain is used to run preprocessing on images before uploading. 31 | It support processing, validations and encoders, all fully customizable. 32 | */ 33 | public class CLDImagePreprocessChain: CLDPreprocessChain { 34 | public override init() { 35 | } 36 | 37 | internal override func decodeResource(_ resourceData: Any) throws -> UIImage? { 38 | if let url = resourceData as? URL { 39 | if let resourceData = try? Data(contentsOf: url) { 40 | return UIImage(data: resourceData) 41 | } 42 | } else if let data = resourceData as? Data { 43 | return UIImage(data: data) 44 | } 45 | 46 | return nil 47 | } 48 | 49 | internal override func verifyEncoder() throws { 50 | if (encoder == nil) { 51 | setEncoder(CLDPreprocessHelpers.defaultImageEncoder) 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Cloudinary/Classes/ios/Uploader/CLDVideoPreprocessHelpers.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import AVKit 3 | 4 | public class CLDVideoPreprocessHelpers { 5 | 6 | private var steps: [(CLDVideoTranscode) throws -> CLDVideoTranscode] = [] 7 | 8 | public func addStep(_ step: @escaping (CLDVideoTranscode) throws -> CLDVideoTranscode) { 9 | steps.append(step) 10 | } 11 | 12 | public static func setOutputFormat(format: AVFileType) -> CLDVideoPreprocessStep { 13 | return { videoTranscode in 14 | do { 15 | try videoTranscode.setOutputFormat(format: format) 16 | } catch { 17 | throw error 18 | } 19 | return videoTranscode 20 | } 21 | } 22 | 23 | public static func setOutputDimensions(dimensions: CGSize) -> CLDVideoPreprocessStep { 24 | return { videoTranscode in 25 | videoTranscode.setOutputDimensions(dimensions: dimensions) 26 | return videoTranscode 27 | } 28 | } 29 | 30 | public static func setCompressionPreset(preset: String) -> CLDVideoPreprocessStep { 31 | return { videoTranscode in 32 | videoTranscode.setCompressionPreset(preset: preset) 33 | return videoTranscode 34 | } 35 | } 36 | 37 | public static func dimensionsValidator(minWidth: CGFloat, maxWidth: CGFloat, minHeight: CGFloat, maxHeight: CGFloat) -> CLDVideoPreprocessStep { 38 | return { videoTranscode in 39 | guard let dimensions = videoTranscode.outputDimensions else { 40 | throw NSError(domain: "CLDVideoPreprocessHelpers", code: -1, userInfo: [NSLocalizedDescriptionKey: "Dimensions not set"]) 41 | } 42 | if dimensions.width < minWidth || dimensions.width > maxWidth || dimensions.height < minHeight || dimensions.height > maxHeight { 43 | throw VideoPreprocessError.dimensionsOutOfRange 44 | } 45 | return videoTranscode 46 | } 47 | } 48 | } 49 | 50 | enum VideoPreprocessError: Error { 51 | case dimensionsOutOfRange 52 | } 53 | -------------------------------------------------------------------------------- /Example/Cloudinary.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Cloudinary.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Cloudinary/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // iOS_Geekle_Conference 4 | // 5 | // Created by Adi Mizrahi on 11/09/2023. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | func applicationDidEnterBackground(_ application: UIApplication) { 21 | CoreDataHelper.shared.saveContext() 22 | } 23 | 24 | func applicationWillTerminate(_ application: UIApplication) { 25 | CoreDataHelper.shared.saveContext() 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app_icon 1.heic", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/AppIcon.appiconset/app_icon 1.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/AppIcon.appiconset/app_icon 1.heic -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Inner/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Inner/ski.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "smart-crop-4 (4) 1.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Inner/ski.imageset/smart-crop-4 (4) 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Delivery/Inner/ski.imageset/smart-crop-4 (4) 1.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Inner/sofa.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "sofa.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Inner/sofa.imageset/sofa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Delivery/Inner/sofa.imageset/sofa.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Video/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Video/instagram.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Group.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Video/tiktok.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "tiktok-white-icon.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Video/tiktok.imageset/tiktok-white-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Video/youtube.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Youtube_shorts_icon 1.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/Video/youtube.imageset/Youtube_shorts_icon 1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/background_normalizing.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "background_normalizing.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/background_normalizing.imageset/background_normalizing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Delivery/background_normalizing.imageset/background_normalizing.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/color_alternation.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "color_alternation.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/color_alternation.imageset/color_alternation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Delivery/color_alternation.imageset/color_alternation.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/delivery-city.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "optimization_hero_gezokr.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/delivery-city.imageset/optimization_hero_gezokr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Delivery/delivery-city.imageset/optimization_hero_gezokr.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/localization_branding.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "localization_branding.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/localization_branding.imageset/localization_branding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Delivery/localization_branding.imageset/localization_branding.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/smart_cropping.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Rectangle 3 (1).png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Delivery/smart_cropping.imageset/Rectangle 3 (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Delivery/smart_cropping.imageset/Rectangle 3 (1).png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Upload/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Upload/question_mark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_help_outline_24px.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Upload/question_mark.imageset/ic_help_outline_24px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Upload/upload_missing.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "picturepile-4.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Upload/upload_missing.imageset/picturepile-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Upload/upload_missing.imageset/picturepile-4.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_bar_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Group 5.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_bar_icon.imageset/Group 5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_comments.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Group 2.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_comments.imageset/Group 2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_discover.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Vector (3).svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_discover.imageset/Vector (3).svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Vector (2).svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_home.imageset/Vector (2).svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_inbox.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Group 3.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_inbox.imageset/Group 3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_like.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Vector (4).svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_like.imageset/Vector (4).svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_more.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon_more.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_more.imageset/icon_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_more.imageset/icon_more.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_music.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "music animation.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_music.imageset/music animation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_music.imageset/music animation.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_note.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Vector (1).svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_note.imageset/Vector (1).svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_share.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Vector (5).svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_share.imageset/Vector (5).svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Video/TikTok/tiktok_social_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Avatar.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Widgets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Widgets/house.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Frame_871_ao5o4r_2_viaeyi.heic", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/Widgets/house.imageset/Frame_871_ao5o4r_2_viaeyi.heic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/Widgets/house.imageset/Frame_871_ao5o4r_2_viaeyi.heic -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/back_arrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "left _arrow.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/back_arrow.imageset/left _arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/car-speed-limiter.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "car-speed-limiter 1.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true, 14 | "template-rendering-intent" : "template" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/car-speed-limiter.imageset/car-speed-limiter 1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/cloudinary_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Layer 1.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/info_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "info_icon.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/info_icon.imageset/info_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Image.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/splash.imageset/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/splash.imageset/Image.png -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/splash_without_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Splashwithoutlogo.jpg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/splash_without_logo.imageset/Splashwithoutlogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Cloudinary/Assets.xcassets/splash_without_logo.imageset/Splashwithoutlogo.jpg -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/upload.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "upload-outline 1.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true, 14 | "template-rendering-intent" : "template" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/upload.imageset/upload-outline 1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/video.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Frame 12.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true, 14 | "template-rendering-intent" : "template" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/video.imageset/Frame 12.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/widgets.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "widgets-outline 1.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true, 14 | "template-rendering-intent" : "template" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/Cloudinary/Assets.xcassets/widgets.imageset/widgets-outline 1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Cloudinary/CldModel.xcdatamodeld/CldModel.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Example/Cloudinary/Cloudinary_Example-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/gradient-first.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xC5", 9 | "green" : "0x48", 10 | "red" : "0x34" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xC5", 27 | "green" : "0x48", 28 | "red" : "0x34" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/gradient-second.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xFA", 9 | "green" : "0xBB", 10 | "red" : "0x28" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xFA", 27 | "green" : "0xBB", 28 | "red" : "0x28" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/primary.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xF7", 9 | "green" : "0x98", 10 | "red" : "0x46" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xF7", 27 | "green" : "0x98", 28 | "red" : "0x46" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/secondary.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x5A", 9 | "green" : "0x47", 10 | "red" : "0x3F" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x5A", 27 | "green" : "0x47", 28 | "red" : "0x3F" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/size_green.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xAE", 9 | "green" : "0xFC", 10 | "red" : "0xB2" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xAE", 27 | "green" : "0xFC", 28 | "red" : "0xB2" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/size_red.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x59", 9 | "green" : "0x59", 10 | "red" : "0xFF" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x59", 27 | "green" : "0x59", 28 | "red" : "0xFF" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/surface.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0x2D", 9 | "green" : "0x24", 10 | "red" : "0x20" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0x2D", 27 | "green" : "0x24", 28 | "red" : "0x20" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Colors.xcassets/text_not_selected.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0xFE", 9 | "green" : "0xFF", 10 | "red" : "0xFF" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0xFE", 27 | "green" : "0xFF", 28 | "red" : "0xFF" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Transformation/DeliveryTransformCollectionController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeliveryTransformCollectionController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 30/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | protocol DeliveryTransformCollectionDelegate { 12 | func transformCellSelected(_ index: Int) 13 | } 14 | 15 | class DeliveryTransformCollectionController: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 16 | 17 | var delegate: DeliveryTransformCollectionDelegate 18 | 19 | init(_ delegate: DeliveryTransformCollectionDelegate) { 20 | self.delegate = delegate 21 | } 22 | 23 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 24 | return 4 25 | } 26 | 27 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 28 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "transfromationCell", for: indexPath) as! TransformationCell 29 | cell.setCellContent(indexPath.row) 30 | return cell 31 | } 32 | 33 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 34 | return CGSize(width: 224, height: 135) 35 | } 36 | 37 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 38 | delegate.transformCellSelected(indexPath.row) 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Transformation/Reveal Image/RevealImageController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RevealImageController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 30/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class RevealImageController: UIViewController { 12 | 13 | @IBOutlet weak var ivMain: RevealImageView! 14 | 15 | func setMainImageView(rightImage: String?, leftImage: String?) { 16 | ImageHelper.getImageFromURL(URL(string: rightImage!)!) { image in 17 | DispatchQueue.main.async { 18 | self.ivMain.rightImage = image 19 | } 20 | } 21 | ImageHelper.getImageFromURL(URL(string: leftImage!)!) { image in 22 | DispatchQueue.main.async { 23 | self.ivMain.leftImage = image 24 | } 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Transformation/Smart Cropping/SmartCroppingController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SmartCroppingController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 30/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class SmartCroppingController: UIViewController { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Transformation/TransformCollectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransformCollectionCell.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 08/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | import Cloudinary 11 | class TransformCollectionCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var lbMain: UILabel! 14 | @IBOutlet weak var ivMain: CLDUIImageView! 15 | 16 | func setCellBy(index: Int) { 17 | switch index { 18 | case 0: 19 | ivMain.cldSetImage(publicId: "Demo%20app%20content/content-aware-crop-4-ski_louxkt", cloudinary: CloudinaryHelper.shared.cloudinary, transformation: CLDTransformation().setCrop("thumb")) 20 | lbMain.text = "Smart Cropping" 21 | case 1: 22 | ivMain.cldSetImage(publicId: "Demo%20app%20content/layers-fashion-2_1_xsfbvm", cloudinary: CloudinaryHelper.shared.cloudinary, transformation: CLDTransformation().setCrop("thumb")) 23 | lbMain.text = "Localization & branding" 24 | case 2: 25 | ivMain.cldSetImage(publicId: "Demo%20app%20content/bgr-furniture-1_isnptj", cloudinary: CloudinaryHelper.shared.cloudinary, transformation: CLDTransformation().setCrop("thumb")) 26 | lbMain.text = "Background normalizing" 27 | case 3: 28 | ivMain.cldSetImage(publicId: "Demo%20app%20content/recolor-tshirt-5_omapls", cloudinary: CloudinaryHelper.shared.cloudinary, transformation: CLDTransformation().setCrop("thumb")) 29 | lbMain.text = "Color Alternation" 30 | default: 31 | break 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Transformation/TransformationCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TransformationCell.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 30/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class TransformationCell: UICollectionViewCell { 12 | @IBOutlet weak var ivMain: UIImageView! 13 | @IBOutlet weak var lbMain: UILabel! 14 | 15 | func setCellContent(_ index: Int) { 16 | switch index { 17 | case 0: 18 | ivMain.image = UIImage(named: "smart_cropping") 19 | lbMain.text = "Smart Cropping" 20 | case 1: 21 | ivMain.image = UIImage(named: "localization_branding") 22 | lbMain.text = "Localization & Branding" 23 | case 2: 24 | ivMain.image = UIImage(named: "background_normalizing") 25 | lbMain.text = "Background normalizing" 26 | case 3: 27 | ivMain.image = UIImage(named: "color_alternation") 28 | lbMain.text = "Color alternation" 29 | default: 30 | break 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Use Cases/DeliveryUseCasesCollectionController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeliveryUseCasesCollectionController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 30/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | protocol DeliverUseCaseCollectionDelegate { 12 | func useCaseCellSelected(_ index: Int) 13 | } 14 | 15 | class DeliveryUseCasesCollectionController: NSObject, UICollectionViewDelegate, UICollectionViewDataSource { 16 | 17 | var delegate: DeliverUseCaseCollectionDelegate 18 | 19 | init(_ delegate: DeliverUseCaseCollectionDelegate) { 20 | self.delegate = delegate 21 | } 22 | 23 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 24 | return 4 25 | } 26 | 27 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 28 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "useCaseCell", for: indexPath) as! UseCaseCell 29 | cell.setCellBy(index: indexPath.row) 30 | return cell 31 | } 32 | 33 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 34 | delegate.useCaseCellSelected(indexPath.row) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Use Cases/Screens/ConditionalProductViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConditionalProductViewController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 22/02/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | import Cloudinary 11 | 12 | class ConditionalProductViewController: UIViewController { 13 | 14 | @IBOutlet weak var ivTopLeft: CLDUIImageView! 15 | @IBOutlet weak var ivTopRight: CLDUIImageView! 16 | @IBOutlet weak var ivBottom: CLDUIImageView! 17 | 18 | 19 | override func viewWillAppear(_ animated: Bool) { 20 | super.viewWillAppear(animated) 21 | setImageViews() 22 | } 23 | 24 | private func setImageViews() { 25 | ivTopLeft.cldSetImage(publicId: "Group_15_jda5ms", cloudinary: CloudinaryHelper.shared.cloudinary) 26 | 27 | ivTopRight.cldSetImage(publicId: "tshirt4_1_si0swc", cloudinary: CloudinaryHelper.shared.cloudinary) 28 | 29 | ivBottom.cldSetImage(publicId: "tshirt4_1_si0swc", cloudinary: CloudinaryHelper.shared.cloudinary, transformation: CLDTransformation().setOverlayWithLayer(CLDLayer().setPublicId(publicId: "Group_15_jda5ms")).setGravity(.northWest).setWidth(0.4).setX(10).setY(10)) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Use Cases/Screens/IntegrateAIViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IntegrateAIViewController.swift 3 | // Cloudinary_Example 4 | // 5 | // Created by Adi Mizrahi on 26/02/2024. 6 | // Copyright © 2024 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import Cloudinary 12 | import AVKit 13 | 14 | class IntegrateAIViewController: UIViewController { 15 | 16 | @IBOutlet weak var vwVideoView: UIView! 17 | 18 | var videoPublicId: String = "" 19 | var player: CLDVideoPlayer! 20 | 21 | override func viewWillAppear(_ animated: Bool) { 22 | super.viewWillAppear(animated) 23 | setVideoView() 24 | } 25 | 26 | private func setVideoView() { 27 | player = CLDVideoPlayer(publicId: videoPublicId, cloudinary: CloudinaryHelper.shared.cloudinary) 28 | let playerLayer = AVPlayerLayer(player: player) 29 | playerLayer.frame = vwVideoView.bounds 30 | playerLayer.videoGravity = .resizeAspectFill 31 | vwVideoView.layer.addSublayer(playerLayer) 32 | 33 | // Add observer for AVPlayerItemDidPlayToEndTime 34 | NotificationCenter.default.addObserver(self, 35 | selector: #selector(playerItemDidReachEnd), 36 | name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, 37 | object: player.currentItem) 38 | 39 | player.play() 40 | } 41 | 42 | @objc private func playerItemDidReachEnd(notification: Notification) { 43 | if let playerItem = notification.object as? AVPlayerItem { 44 | // Seek to the start of the video to loop it 45 | playerItem.seek(to: .zero) 46 | player.play() 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Use Cases/Screens/NormalizingProductAssetsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NormalizingProductAssetsViewController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 21/02/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | import Cloudinary 11 | 12 | class NormalizingProductAssetsViewController: UIViewController { 13 | 14 | @IBOutlet weak var ivTopLeft: CLDUIImageView! 15 | @IBOutlet weak var ivTopRight: CLDUIImageView! 16 | @IBOutlet weak var ivMidRight: CLDUIImageView! 17 | @IBOutlet weak var ivBottomLeft: CLDUIImageView! 18 | @IBOutlet weak var ivBottomMid: CLDUIImageView! 19 | @IBOutlet weak var ivBottomRight: CLDUIImageView! 20 | 21 | override func viewWillAppear(_ animated: Bool) { 22 | super.viewWillAppear(animated) 23 | setImageViews() 24 | } 25 | 26 | private func setImageViews() { 27 | ivTopLeft.cldSetImage(publicId: "pexels-aditya-aiyar-1407354_tiw4bv", cloudinary: CloudinaryHelper.shared.cloudinary) 28 | ivTopRight.cldSetImage(publicId: "pexels-mnz-1670766_n9hfoi", cloudinary: CloudinaryHelper.shared.cloudinary) 29 | ivMidRight.cldSetImage(publicId: "pexels-wendy-wei-12511453_b4shho", cloudinary: CloudinaryHelper.shared.cloudinary) 30 | ivBottomLeft.cldSetImage(publicId: "Rectangle_1434_fcnobi", cloudinary: CloudinaryHelper.shared.cloudinary) 31 | ivBottomMid.cldSetImage(publicId: "Rectangle_1435_mwtszu", cloudinary: CloudinaryHelper.shared.cloudinary) 32 | ivBottomRight.cldSetImage(publicId: "Rectangle_1436_kdsfld", cloudinary: CloudinaryHelper.shared.cloudinary) 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Use Cases/UseCaseCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UseCaseCell.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 30/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class UseCaseCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var lbMain: UILabel! 14 | @IBOutlet weak var vwGradient: GradientView! 15 | 16 | func setCellBy(index: Int) { 17 | switch index { 18 | case 0: 19 | lbMain.text = "Normalizing Product Assets - Sizing" 20 | case 1: 21 | lbMain.text = "Conditional Product Badging" 22 | case 2: 23 | lbMain.text = "Adapt video to any screen" 24 | case 3: 25 | lbMain.text = "Integrate AI-generated backgrounds" 26 | default: 27 | break 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Use Cases/UseCaseCollectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UseCaseCollectionCell.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 21/02/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class UseCaseCollectionCell: UICollectionViewCell { 12 | @IBOutlet weak var lbMain: UILabel! 13 | 14 | func setCellBy(index: Int) { 15 | switch index { 16 | case 0: 17 | lbMain.text = "Normalizing Product Assets - Sizing" 18 | case 1: 19 | lbMain.text = "Conditional Product Badging" 20 | case 2: 21 | lbMain.text = "Adapt video to any screen" 22 | case 3: 23 | lbMain.text = "Integrate AI-generated backgrounds" 24 | default: 25 | break 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Transform/Use Cases/UseCasesCollectionController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UseCasesCollectionController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 21/02/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | protocol UseCasesCollectionDelegate { 12 | func cellSelected(_ index: Int) 13 | } 14 | 15 | class UseCasesCollectionController: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 16 | 17 | var delegate: UseCasesCollectionDelegate 18 | 19 | var selectedCellIndex = 0 20 | 21 | init(_ delegate: UseCasesCollectionDelegate) { 22 | self.delegate = delegate 23 | } 24 | 25 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 26 | 4 27 | } 28 | 29 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 30 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "UseCaseCollectionCell", for: indexPath) as! UseCaseCollectionCell 31 | cell.setCellBy(index: indexPath.row) 32 | setSelectedCell(cell, index: indexPath.row) 33 | return cell 34 | } 35 | 36 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 37 | selectedCellIndex = indexPath.row 38 | delegate.cellSelected(indexPath.row) 39 | collectionView.reloadData() 40 | } 41 | 42 | private func setSelectedCell(_ cell: UseCaseCollectionCell, index: Int) { 43 | if index == selectedCellIndex { 44 | cell.isSelected = true 45 | cell.layer.borderColor = UIColor(named: "primary")?.cgColor 46 | cell.layer.borderWidth = 3 47 | cell.layer.cornerRadius = 4 48 | } else { 49 | cell.layer.borderWidth = 0 50 | } 51 | } 52 | 53 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 54 | return CGSize(width: 80, height: 116) 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Upload/InnerUploadFrame.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InnerUploadFrame.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 28/12/2023. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class InnerUploadFrame: UIView { 12 | 13 | @IBOutlet weak var lbTitle: UILabel! 14 | @IBOutlet weak var lbSubtitle: UILabel! 15 | @IBOutlet weak var vwGradientView: GradientView! 16 | 17 | override init(frame: CGRect) { 18 | super.init(frame: frame) 19 | commonInit() 20 | } 21 | 22 | required init?(coder: NSCoder) { 23 | super.init(coder: coder) 24 | commonInit() 25 | } 26 | 27 | private func commonInit() { 28 | let nibName = String(describing: type(of: self)) 29 | if let view = Bundle.main.loadNibNamed(nibName, owner: self, options: nil)?.first as? UIView { 30 | view.frame = bounds 31 | addSubview(view) 32 | } 33 | vwGradientView.layer.cornerRadius = vwGradientView.frame.height / 2 34 | } 35 | 36 | func setTitle(title: String) { 37 | lbTitle.text = title 38 | } 39 | 40 | func setSubtitle(subtitle: String) { 41 | lbSubtitle.text = subtitle 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Upload/Single Upload/SingleUploadCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingleUploadCell.swift 3 | // Cloudinary_Example 4 | // 5 | // Created by Adi Mizrahi on 18/07/2024. 6 | // Copyright © 2024 CocoaPods. All rights reserved. 7 | // 8 | 9 | 10 | import Foundation 11 | import UIKit 12 | import Cloudinary 13 | class SingleUploadCell: UICollectionViewCell { 14 | @IBOutlet weak var ivMain: CLDUIImageView! 15 | 16 | func setImage(_ url: String, _ cloudinary: CLDCloudinary) { 17 | var urlString = url 18 | if urlString.contains("video") { 19 | urlString = replaceExtension(urlString: urlString) ?? "" 20 | ivMain.cldSetImage(urlString, cloudinary: cloudinary) 21 | return 22 | } 23 | guard let url = URL(string: urlString) else { 24 | return 25 | } 26 | let publicId = url.lastPathComponent 27 | ivMain.cldSetImage(publicId: publicId, cloudinary: cloudinary, transformation: CLDTransformation().setCrop("thumb")) 28 | } 29 | 30 | func replaceExtension(urlString: String) -> String? { 31 | guard let url = URL(string: urlString) else { 32 | return nil // Invalid URL 33 | } 34 | 35 | // Get the last path component 36 | let lastComponent = url.lastPathComponent 37 | 38 | // Get the path extension 39 | let pathExtension = (lastComponent as NSString).pathExtension 40 | 41 | // Replace the path extension with ".jpg" 42 | let newLastPathComponent = (lastComponent as NSString).deletingPathExtension + ".jpg" 43 | 44 | // Create a new URL instance with the updated path component 45 | if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) { 46 | urlComponents.path = urlComponents.path.replacingOccurrences(of: lastComponent, with: newLastPathComponent) 47 | 48 | // Get the updated URL string 49 | if let updatedURLString = urlComponents.string { 50 | return updatedURLString 51 | } 52 | } 53 | 54 | return urlString // Return original URL if there's any failure in updating the URL string 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Upload/Single Upload/SingleUploadCollectionLayout.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingleUploadCollectionLayout.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 12/05/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class SingleUploadCollectionLayout: UICollectionViewFlowLayout { 12 | 13 | var singleItemAttributes: UICollectionViewLayoutAttributes? 14 | 15 | override func prepare() { 16 | super.prepare() 17 | 18 | guard let collectionView = collectionView else { return } 19 | 20 | // Calculate item size to occupy one-third of the collection view's width 21 | let itemWidth = (collectionView.bounds.width - minimumInteritemSpacing * 2 - minimumLineSpacing * 2) / 3 22 | itemSize = CGSize(width: itemWidth, height: itemWidth) 23 | 24 | // Calculate horizontal inset to center items 25 | let inset = (collectionView.bounds.width - CGFloat(3) * itemWidth - minimumInteritemSpacing * 2) / 2 26 | 27 | // Set section inset 28 | sectionInset = UIEdgeInsets(top: sectionInset.top, left: inset, bottom: sectionInset.bottom, right: inset) 29 | 30 | // Adjust alignment for single item 31 | if collectionView.numberOfItems(inSection: 0) == 1 { 32 | let indexPath = IndexPath(item: 0, section: 0) 33 | singleItemAttributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) 34 | singleItemAttributes?.frame.origin = CGPoint(x: sectionInset.left, y: sectionInset.top) 35 | } else { 36 | singleItemAttributes = nil 37 | } 38 | } 39 | 40 | override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 41 | if let singleItemAttributes = singleItemAttributes { 42 | return [singleItemAttributes] 43 | } else { 44 | return super.layoutAttributesForElements(in: rect) 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Video/Video Feed/VideoFeedCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoFeedCell.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 31/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class VideoFeedCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var vwGradientView: GradientView! 14 | @IBOutlet weak var ivMain: UIImageView! 15 | 16 | func setImage(_ index: Int) { 17 | self.layer.cornerRadius = 4 18 | self.layer.masksToBounds = false 19 | vwGradientView.layer.cornerRadius = 4 20 | vwGradientView.layer.masksToBounds = false 21 | switch index { 22 | case 0: 23 | ivMain.image = UIImage(named: "tiktok") 24 | case 1: 25 | ivMain.image = UIImage(named: "instagram") 26 | case 2: 27 | ivMain.image = UIImage(named: "youtube") 28 | default: 29 | break 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Inner Views/Video/VideoFeedCollectionController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoFeedCollectionController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 31/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | protocol VideoFeedCollectionDelegate { 12 | func cellClicked(_ index: Int) 13 | } 14 | 15 | class VideoFeedCollectionController: NSObject, UICollectionViewDelegate, UICollectionViewDataSource { 16 | 17 | var delegate: VideoFeedCollectionDelegate 18 | 19 | init(_ delegate: VideoFeedCollectionDelegate) { 20 | self.delegate = delegate 21 | } 22 | 23 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 24 | return 3 25 | } 26 | 27 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 28 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoFeedCell", for: indexPath) as! VideoFeedCell 29 | cell.setImage(indexPath.row) 30 | cell.layer.cornerRadius = 4 31 | cell.layer.masksToBounds = false 32 | cell.contentView.layer.cornerRadius = 4 33 | cell.contentView.layer.masksToBounds = false 34 | return cell 35 | } 36 | 37 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 38 | delegate.cellClicked(indexPath.row) 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/SplashViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SplashController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 27/12/2023. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | class SplashViewController: UIViewController { 11 | override func viewDidAppear(_ animated: Bool) { 12 | super.viewDidAppear(animated) 13 | let delayInSeconds: TimeInterval = 2 14 | DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { 15 | self.transitionToMainController() 16 | } 17 | EventsHandler.shared.logEvent(event: EventObject(name: "Splash")) 18 | } 19 | 20 | func transitionToMainController() { 21 | // Instantiate your main view controller 22 | let storyboard = UIStoryboard(name: "Main", bundle: nil) // Replace "Main" with your actual storyboard name 23 | let mainViewController = storyboard.instantiateViewController(withIdentifier: "MainViewController") // Replace "MainViewController" with your actual view controller identifier 24 | 25 | // Transition to the main view controller 26 | if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, 27 | let delegate = windowScene.delegate as? SceneDelegate { 28 | delegate.window?.rootViewController = mainViewController 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Video Feed/Controllers/VideoFeedContainerController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoFeedContainerController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 04/02/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class VideoFeedContainerController: UIViewController { 12 | @IBOutlet weak var vwFeedContainer: UIView! 13 | var videoURL: String! 14 | var controller: VideoFeedViewController! 15 | 16 | 17 | func setupPlayer() { 18 | if isViewLoaded == false { 19 | _ = view 20 | } 21 | 22 | controller = UIStoryboard(name: "VideoFeed", bundle: nil).instantiateViewController(identifier: "VideoFeedViewController") 23 | if let controller = controller { 24 | controller.videoURL = videoURL 25 | controller.setupPlayer() 26 | 27 | controller.view.frame = vwFeedContainer.bounds 28 | vwFeedContainer.addSubview(controller.view) 29 | controller.didMove(toParent: self) 30 | } 31 | } 32 | 33 | func playVideo() { 34 | controller.playVideo() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Video Feed/Controllers/VideoFeedController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoFeedController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 04/02/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class VideoFeedController: UIViewController { 12 | @IBOutlet weak var vwBack: UIView! 13 | 14 | override func viewWillAppear(_ animated: Bool) { 15 | super.viewWillAppear(animated) 16 | setBackButton() 17 | } 18 | 19 | override func viewDidAppear(_ animated: Bool) { 20 | super.viewDidAppear(animated) 21 | self.view.bringSubviewToFront(vwBack) 22 | } 23 | 24 | private func setBackButton() { 25 | let tapGesture = UITapGestureRecognizer(target: self, action: #selector(backClicked)) 26 | vwBack.addGestureRecognizer(tapGesture) 27 | } 28 | 29 | 30 | @objc private func backClicked() { 31 | self.dismiss(animated: true) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Video Feed/Controllers/VideoSocialOverlaysController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoSocialOverlaysController.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 04/02/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class VideoSocialOverlaysController: UIViewController { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Video Feed/Helpers/VideoHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoHelper.swift 3 | // ios-video-testing 4 | // 5 | // Created by Adi Mizrahi on 16/11/2023. 6 | // 7 | 8 | import Foundation 9 | class VideoHelper { 10 | static func parsePlist() -> [String]? { 11 | if let path = Bundle.main.path(forResource: "video_links", ofType: "plist") { 12 | let videoDictonary = NSDictionary(contentsOfFile: path) 13 | if let videoLinks = videoDictonary?.allValues as? [String] { 14 | return videoLinks 15 | } 16 | 17 | } 18 | return nil 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Video Feed/Resources/video_links.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | video1 6 | https://res.cloudinary.com/mobiledemoapp/video/upload/ar_9:16,c_fill,g_auto,w_600/f_auto:video,q_auto:eco/sprort-2_zgsr5k.mp4 7 | video2 8 | https://res.cloudinary.com/mobiledemoapp/video/upload/ar_9:16,c_fill,g_auto,w_600/f_auto:video,q_auto:eco/fashion-2_ewukga.mp4 9 | video3 10 | https://res.cloudinary.com/demo/video/upload/ar_9:16,c_fill,g_auto,w_600/f_auto:video,q_auto:eco/v1/docs/surfers 11 | video4 12 | https://res.cloudinary.com/mobiledemoapp/video/upload/ar_9:16,c_fill,g_auto,w_600/f_auto:video,q_auto:eco/fashion-1_1_kuwihy.mp4 13 | video5 14 | https://res.cloudinary.com/demo/video/upload/ar_9:16,c_fill,g_auto,w_600/f_auto:video,q_auto:eco/v1/docs/car-film 15 | video6 16 | https://res.cloudinary.com/demo/video/upload/ar_9:16,c_fill,g_auto,w_600/f_auto:video,q_auto:eco/v1/docs/rocky-mountains 17 | video7 18 | https://res.cloudinary.com/demo/video/upload/ar_9:16,c_fill,g_auto,w_600/f_auto:video,q_auto:eco/v1/docs/sailing_boat 19 | 20 | 21 | -------------------------------------------------------------------------------- /Example/Cloudinary/Controllers/Widgets/ImageWidgetViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageWidgetViewController.swift 3 | // iOS_Geekle_Conference 4 | // 5 | // Created by Adi Mizrahi on 19/09/2023. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | import Cloudinary 11 | 12 | class ImageWidgetViewController: UIViewController { 13 | @IBOutlet weak var ivLocal: CLDUIImageView! 14 | @IBOutlet weak var ivRemote: CLDUIImageView! 15 | @IBOutlet weak var ivCloudinary: CLDUIImageView! 16 | 17 | let cloudinary = CloudinaryHelper.shared.cloudinary 18 | 19 | 20 | override func viewWillAppear(_ animated: Bool) { 21 | super.viewWillAppear(animated) 22 | setLocalImage() 23 | setRemoteImage() 24 | setCloudinaryImage() 25 | EventsHandler.shared.logEvent(event: EventObject(name: "Image Widget")) 26 | } 27 | 28 | private func setLocalImage() { 29 | ivLocal.image = UIImage(named: "house") 30 | } 31 | 32 | private func setRemoteImage() { 33 | ivRemote.cldSetImage("https://res.cloudinary.com/mobiledemoapp/image/upload/v1706628181/Demo%20app%20content/Frame_871_ao5o4r.jpg", cloudinary: cloudinary) 34 | } 35 | 36 | private func setCloudinaryImage() { 37 | ivCloudinary.cldSetImage(publicId: "Demo%20app%20content/Frame_871_ao5o4r", cloudinary: cloudinary) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Example/Cloudinary/Core Data/AssetItems+CoreDataClass.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AssetItems_CoreDataClass.swift 3 | // Cloudinary_Example 4 | // 5 | // Created by Adi Mizrahi on 18/07/2024. 6 | // Copyright © 2024 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | 13 | public class AssetItems: NSManagedObject { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Core Data/AssetItems+CoreDataProperties.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AssetItems+CoreDataProperties.swift 3 | // Cloudinary_Example 4 | // 5 | // Created by Adi Mizrahi on 18/07/2024. 6 | // Copyright © 2024 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreData 11 | 12 | 13 | extension AssetItems { 14 | 15 | @nonobjc public class func fetchRequest() -> NSFetchRequest { 16 | return NSFetchRequest(entityName: "AssetItems") 17 | } 18 | 19 | @NSManaged public var deliveryType: String 20 | @NSManaged public var assetType: String 21 | @NSManaged public var transformation: String? 22 | @NSManaged public var publicId: String 23 | @NSManaged public var url: String 24 | 25 | } 26 | 27 | extension AssetItems : Identifiable { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Example/Cloudinary/Core Data/AssetModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AssetModel.swift 3 | // Cloudinary_Example 4 | // 5 | // Created by Adi Mizrahi on 18/07/2024. 6 | // Copyright © 2024 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | class AssetModel { 11 | private var deliveryType: String 12 | private var assetType: String 13 | private var transformation: String? 14 | private var publicId: String 15 | private var url: String 16 | 17 | init(deliveryType: String, assetType: String, transformation: String? = nil, publicId: String, url: String) { 18 | self.deliveryType = deliveryType 19 | self.assetType = assetType 20 | self.transformation = transformation 21 | self.publicId = publicId 22 | self.url = url 23 | } 24 | 25 | func setDeliveryType(_ type: String) { 26 | deliveryType = type 27 | } 28 | 29 | func setAssetType(_ type: String) { 30 | assetType = type 31 | } 32 | 33 | func setTransformation(_ trans: String) { 34 | transformation = trans 35 | } 36 | 37 | func setPublicId(_ id: String) { 38 | publicId = id 39 | } 40 | 41 | func setUrl(_ url: String) { 42 | self.url = url 43 | } 44 | 45 | func getDeliveryType() -> String { 46 | return deliveryType 47 | } 48 | 49 | func getAssetType() -> String { 50 | return assetType 51 | } 52 | 53 | func getTransformation() -> String? { 54 | return transformation 55 | } 56 | 57 | func getPublicId() -> String { 58 | return publicId 59 | } 60 | 61 | func getUrl() -> String { 62 | return url 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Example/Cloudinary/Core Data/AssetModel.xcdatamodeld/Model.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Example/Cloudinary/Custom Views/GradientView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GradientView.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 27/12/2023. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | @IBDesignable 11 | class GradientView: UIView { 12 | @IBInspectable var firstColor: UIColor = UIColor.clear { 13 | didSet { 14 | updateView() 15 | } 16 | } 17 | @IBInspectable var secondColor: UIColor = UIColor.clear { 18 | didSet { 19 | updateView() 20 | } 21 | } 22 | 23 | override class var layerClass: AnyClass { 24 | get { 25 | return CAGradientLayer.self 26 | } 27 | } 28 | 29 | override func layoutSubviews() { 30 | super.layoutSubviews() 31 | updateView() 32 | } 33 | 34 | func updateView() { 35 | guard let gradientLayer = layer as? CAGradientLayer else { return } 36 | 37 | gradientLayer.colors = [UIColor(red: 0.204, green: 0.282, blue: 0.773, alpha: 1).cgColor, 38 | UIColor(red: 0.157, green: 0.733, blue: 0.98, alpha: 1).cgColor 39 | ] 40 | gradientLayer.locations = [0, 1] 41 | gradientLayer.startPoint = CGPoint(x: 0, y: 0) // Top-left 42 | gradientLayer.endPoint = CGPoint(x: 1, y: 1) // Bottom-right 43 | // gradientLayer.transform = CATransform3DMakeAffineTransform(CGAffineTransform(a: 0.98, b: 0.98, c: -0.98, d: 0.45, tx: 0.5, ty: -0.21)) 44 | gradientLayer.position = self.center 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Example/Cloudinary/Custom Views/ToolBar/Item/ToolbarItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ToolbarItem.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 27/12/2023. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | class ToolbarItem: UIView { 11 | 12 | @IBOutlet weak var ivMain: UIImageView! 13 | @IBOutlet weak var lbMain: UILabel! 14 | 15 | override init(frame: CGRect) { 16 | super.init(frame: frame) 17 | commonInit() 18 | } 19 | 20 | required init?(coder aDecoder: NSCoder) { 21 | super.init(coder: aDecoder) 22 | commonInit() 23 | } 24 | 25 | private func commonInit() { 26 | guard let view = loadViewFromNib() else { return } 27 | view.frame = bounds 28 | view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 29 | addSubview(view) 30 | } 31 | 32 | private func loadViewFromNib() -> UIView? { 33 | let nib = UINib(nibName: "ToolbarItem", bundle: nil) 34 | return nib.instantiate(withOwner: self, options: nil).first as? UIView 35 | } 36 | 37 | func selectItem() { 38 | ivMain.tintColor = UIColor(named: "primary") 39 | lbMain.textColor = UIColor(named: "primary") 40 | } 41 | 42 | func unselectItem() { 43 | ivMain.tintColor = UIColor(named: "text_not_selected") 44 | lbMain.textColor = UIColor(named: "text_not_selected") 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Example/Cloudinary/Custom Views/Upload Loading View/UploadLoadingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UploadLoadingView.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 11/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | class UploadLoadingView: UIView { 12 | 13 | @IBOutlet weak var aiLoading: UIActivityIndicatorView! 14 | override init(frame: CGRect) { 15 | super.init(frame: frame) 16 | commonInit() 17 | } 18 | 19 | required init?(coder aDecoder: NSCoder) { 20 | super.init(coder: aDecoder) 21 | commonInit() 22 | } 23 | 24 | private func commonInit() { 25 | guard let view = loadViewFromNib() else { return } 26 | view.frame = bounds 27 | view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 28 | view.layer.cornerRadius = 4 29 | addSubview(view) 30 | } 31 | 32 | private func loadViewFromNib() -> UIView? { 33 | let nib = UINib(nibName: "UploadLoadingView", bundle: nil) 34 | return nib.instantiate(withOwner: self, options: nil).first as? UIView 35 | } 36 | 37 | func startAnimation() { 38 | aiLoading.startAnimating() 39 | } 40 | 41 | func stopAnimation() { 42 | aiLoading.stopAnimating() 43 | } 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/Cloudinary/Extensions/Double+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Double+Extension.swift 3 | // iOS_Geekle_Conference 4 | // 5 | // Created by Adi Mizrahi on 18/09/2023. 6 | // 7 | 8 | import Foundation 9 | extension Double { 10 | /// Rounds the double to decimal places value 11 | func rounded(toPlaces places:Int) -> Double { 12 | let divisor = pow(10.0, Double(places)) 13 | return (self * divisor).rounded() / divisor 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/GoogleService-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | API_KEY 6 | AIzaSyCFgj2Omu6hBF7frbKT-LHQHJmXiiK2OOo 7 | GCM_SENDER_ID 8 | 554013255617 9 | PLIST_VERSION 10 | 1 11 | BUNDLE_ID 12 | com.cloudinary.Cloudinary-Sample-App 13 | PROJECT_ID 14 | ios-sample-app-d3d7d 15 | STORAGE_BUCKET 16 | ios-sample-app-d3d7d.appspot.com 17 | IS_ADS_ENABLED 18 | 19 | IS_ANALYTICS_ENABLED 20 | 21 | IS_APPINVITE_ENABLED 22 | 23 | IS_GCM_ENABLED 24 | 25 | IS_SIGNIN_ENABLED 26 | 27 | GOOGLE_APP_ID 28 | 1:554013255617:ios:8a787dcf8bc7e668ca3140 29 | 30 | -------------------------------------------------------------------------------- /Example/Cloudinary/Helpers/Events/EventObject.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventObject.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 05/02/2024. 6 | // 7 | 8 | import Foundation 9 | 10 | class EventObject{ 11 | var eventName:String?; 12 | var eventAttributes:[String:String]?; 13 | 14 | init(name: String, attributes: [String: String]? = nil) { 15 | self.eventName = name 16 | self.eventAttributes = attributes 17 | } 18 | 19 | func getAttributes() -> [String:String]? { 20 | return eventAttributes; 21 | } 22 | 23 | func setEventAttribute(_ key:String,_ value:String) { 24 | eventAttributes![key] = value; 25 | } 26 | 27 | func setEventAttributes(attrs:[String:String]) { 28 | self.eventAttributes = attrs; 29 | } 30 | 31 | func getEventName()->String { 32 | return eventName!; 33 | } 34 | 35 | func setEventName(name:String) { 36 | eventName = name; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Cloudinary/Helpers/Events/EventsHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventsHandler.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 05/02/2024. 6 | // 7 | 8 | import Foundation 9 | import Foundation 10 | class EventsHandler{ 11 | static let shared = EventsHandler(); 12 | private var providersList = [EventsProvider](); 13 | private init() { 14 | initProvidersList(); 15 | } 16 | 17 | private func initProvidersList(){ 18 | providersList.append(FirebaseEventsHandler()) 19 | } 20 | 21 | func logEvent(event:EventObject){ 22 | for provider in providersList{ 23 | provider.logEvent(event: event); 24 | } 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Example/Cloudinary/Helpers/Events/EventsProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EventsProvider.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 05/02/2024. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol EventsProvider { 11 | func logEvent(event: EventObject) 12 | } 13 | -------------------------------------------------------------------------------- /Example/Cloudinary/Helpers/Events/FirebaseEventsHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirebaseEventsHandler.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 05/02/2024. 6 | // 7 | 8 | import Foundation 9 | //import Firebase 10 | 11 | class FirebaseEventsHandler: EventsProvider { 12 | func logEvent(event: EventObject) { 13 | // Analytics.logEvent(event.getEventName(), parameters: event.getAttributes()) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Example/Cloudinary/Helpers/ImageHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageHelper.swift 3 | // Cloudinary_Sample_App 4 | // 5 | // Created by Adi Mizrahi on 09/01/2024. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | class ImageHelper { 11 | static func getImageFromURL(_ url: URL, completion: @escaping (UIImage?) -> Void) { 12 | URLSession.shared.dataTask(with: url) { data, response, error in 13 | guard let data = data, error == nil else { 14 | completion(nil) 15 | return 16 | } 17 | 18 | if let image = UIImage(data: data) { 19 | completion(image) 20 | } else { 21 | completion(nil) 22 | } 23 | }.resume() 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Example/Cloudinary/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleName 12 | Cloudinary 13 | CFBundleShortVersionString 14 | 1.0 15 | CFBundleVersion 16 | 1 17 | NSPhotoLibraryUsageDescription 18 | The app needs access to the photo library in order for you to choose photos and videos for uploading 19 | UIApplicationSceneManifest 20 | 21 | UIApplicationSupportsMultipleScenes 22 | 23 | UISceneConfigurations 24 | 25 | UIWindowSceneSessionRoleApplication 26 | 27 | 28 | UISceneConfigurationName 29 | Default Configuration 30 | UISceneDelegateClassName 31 | $(PRODUCT_MODULE_NAME).SceneDelegate 32 | UISceneStoryboardFile 33 | Splash 34 | 35 | 36 | 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen.storyboard 40 | UIStatusBarStyle 41 | 42 | UISupportedInterfaceOrientations 43 | 44 | UIInterfaceOrientationPortrait 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/Cloudinary/Utils/CloudinaryHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CloudinaryHelper.swift 3 | // iOS_Geekle_Conference 4 | // 5 | // Created by Adi Mizrahi on 12/09/2023. 6 | // 7 | 8 | import Foundation 9 | import Cloudinary 10 | 11 | class CloudinaryHelper { 12 | static let shared = CloudinaryHelper() 13 | 14 | var cloudinary: CLDCloudinary 15 | 16 | init() { 17 | cloudinary = CLDCloudinary(configuration: CLDConfiguration(cloudName: "mobiledemoapp", secure: true)) 18 | } 19 | 20 | func setUploadCloud(_ cloudName: String?) { 21 | guard let cloudName = cloudName else { 22 | return 23 | } 24 | UserDefaults.standard.set(cloudName, forKey: "uploadCloudName") 25 | } 26 | 27 | func getUploadCloud() -> String? { 28 | guard let cloudName = UserDefaults.standard.value(forKey: "uploadCloudName") as? String else { 29 | return nil 30 | } 31 | return cloudName 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '13.0' 2 | use_frameworks! 3 | 4 | target 'Cloudinary_Example' do 5 | pod 'Cloudinary', :path => '../' 6 | # pod 'Firebase' 7 | 8 | target 'Cloudinary_Tests' do 9 | inherit! :search_paths 10 | 11 | # For view base tests add FBSnapshotTestCase 12 | #pod 'FBSnapshotTestCase' , '~> 2.1.4' 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Example/README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | This is a very simple application that integrates the [Cloudinary iOS SDK](https://github.com/cloudinary/cloudinary_ios). 3 | The application has the following samples: 4 | 1. Delivery 5 | 1. Optimization 6 | 2. Transform 7 | 3. Use cases 8 | 2. Upload 9 | 1. Upload 10 | 2. Upload large 11 | 3. Fetch upload 12 | 3. UI 13 | 1. Upload Widget 14 | 2. Image Widget 15 | 4. Video 16 | 1. Video Widget 17 | 2. Video feed 18 | 19 | ## Installation 20 | To use the sample project please go to the Example directory and run the following command: 21 | 22 | ```bash 23 | pod install 24 | ``` 25 | 26 | ## Configuration 27 | Once you clone this repository there are two required steps to build the sample app: 28 | 1. Configure your Cloudinary cloud name for the app: 29 | * Once you open the upload controller you'll be asked to enter your cloud name, you can find your cloud name at the top of your [dashboard.](https://console.cloudinary.com/pm/developer-dashboard) 30 | 2. Create an upload preset named 'ios_sample' in your cloudinary account console: 31 | * Login to your [Cloudinary console](https://cloudinary.com/console), go to settings>upload, scroll down 32 | to Upload Presets and click `Add upload preset`. Alternatively, head directly to the [new preset page](https://console.cloudinary.com/console/upload_presets/new). 33 | * Type in `ios_sample` as the name and save, leaving all the fields with their default values. 34 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/BaseTestCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseTestCase.swift 3 | // 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | // 23 | 24 | @testable import Cloudinary 25 | import Foundation 26 | import XCTest 27 | 28 | class BaseTestCase: XCTestCase { 29 | let timeout: TimeInterval = 120.0 30 | 31 | static var testDirectoryURL: URL { return FileManager.temporaryDirectoryURL.appendingPathComponent("org.cloudinary.tests") } 32 | var testDirectoryURL: URL { return BaseTestCase.testDirectoryURL } 33 | 34 | override func setUp() { 35 | super.setUp() 36 | 37 | FileManager.removeAllItemsInsideDirectory(at: testDirectoryURL) 38 | FileManager.createDirectory(at: testDirectoryURL) 39 | } 40 | 41 | override func setUpWithError() throws { 42 | 43 | try XCTSkipIf(shouldSkipTest(), "test skipped") 44 | 45 | try super.setUpWithError() 46 | } 47 | 48 | /** 49 | override this method to skip tests when needed 50 | */ 51 | func shouldSkipTest() -> Bool { 52 | return false 53 | } 54 | 55 | func url(forResource fileName: String, withExtension ext: String) -> URL { 56 | let bundle = Bundle(for: BaseTestCase.self) 57 | return bundle.url(forResource: fileName, withExtension: ext)! 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/ObjcBaseTestCase.h: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcBaseTestCase.h 3 | // 4 | // Copyright (c) 2020 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #import 26 | #import 27 | #import "Cloudinary_Tests-Swift.h" 28 | 29 | 30 | @interface ObjcBaseTestCase: XCTestCase 31 | 32 | @property (nonatomic, assign) NSTimeInterval timeout; 33 | 34 | - (BOOL)shouldSkipTest; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/ObjcBaseTestCase.m: -------------------------------------------------------------------------------- 1 | // 2 | // ObjcBaseTestCase.m 3 | // Cloudinary_Tests 4 | // 5 | // Created by Oz Deutsch on 24/09/2020. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | #import "ObjcBaseTestCase.h" 10 | 11 | @implementation ObjcBaseTestCase 12 | 13 | - (BOOL)setUpWithError:(NSError *__autoreleasing _Nullable *)error { 14 | 15 | XCTSkipIf([self shouldSkipTest], "test skipped"); 16 | 17 | return [super setUpWithError:error]; 18 | } 19 | 20 | /** 21 | override this method to skip tests when needed 22 | */ 23 | - (BOOL)shouldSkipTest { 24 | return false; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Images/rainbow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/BaseNetwork/Resources/Images/rainbow.jpg -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Images/unicorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/BaseNetwork/Resources/Images/unicorn.png -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/JSON/empty_data.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/BaseNetwork/Resources/Responses/JSON/empty_data.json -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/JSON/invalid_data.json: -------------------------------------------------------------------------------- 1 | this is not going 2 | "to" be happy json 3 | data at all 4 | { 5 | "10": whoops 6 | } 7 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/JSON/valid_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "team": "royals", 3 | "score": 23 4 | } 5 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/Property List/empty.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/BaseNetwork/Resources/Responses/Property List/empty.data -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/Property List/invalid.data: -------------------------------------------------------------------------------- 1 | this is not going 2 | "to" be happy json 3 | data at all 4 | { 5 | "10": whoops 6 | } 7 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/Property List/valid.data: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 4.0.0-beta.2 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/String/empty_string.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/BaseNetwork/Resources/Responses/String/empty_string.txt -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/String/utf32_string.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/BaseNetwork/Resources/Responses/String/utf32_string.txt -------------------------------------------------------------------------------- /Example/Tests/BaseNetwork/Resources/Responses/String/utf8_string.txt: -------------------------------------------------------------------------------- 1 | random data -------------------------------------------------------------------------------- /Example/Tests/FileUtilsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FileUtilsTests.swift 3 | // CloudinaryTests 4 | // 5 | // Created by Nitzan Jaitman on 24/09/2017. 6 | // Copyright © 2017 Cloudinary. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import XCTest 11 | @testable import Cloudinary 12 | 13 | class FileUtilsTests: BaseTestCase { 14 | override func setUp() { 15 | super.setUp() 16 | } 17 | 18 | override func tearDown() { 19 | super.tearDown() 20 | } 21 | 22 | func testSplitFile() { 23 | 24 | let url = Bundle(for: FileUtilsTests.self).url(forResource: "borderCollie", withExtension: "jpg")! 25 | let (_, files) = CLDFileUtils.splitFile(url: url, chunkSize: 1024 * 20)! 26 | let totalSize = CLDFileUtils.getFileSize(url: url) 27 | 28 | var sum: Int64 = 0 29 | 30 | for file in files { 31 | XCTAssertTrue(FileManager.default.fileExists(atPath: file.url.path)) 32 | sum += Int64(file.length) 33 | } 34 | 35 | XCTAssertEqual(sum, totalSize) 36 | } 37 | 38 | func testRemoveFiles(){ 39 | let url = Bundle.init(for: FileUtilsTests.self).url(forResource: "borderCollie", withExtension: "jpg")! 40 | let (base, files) = CLDFileUtils.splitFile(url: url, chunkSize: 1024 * 20)! 41 | 42 | for file in files { 43 | XCTAssertTrue(FileManager.default.fileExists(atPath: file.url.path)) 44 | } 45 | 46 | CLDFileUtils.removeFile(file: base!) 47 | XCTAssertFalse(FileManager.default.fileExists(atPath: base!.path)) 48 | 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Example/Tests/NetworkTests/NetworkBaseTests/NetworkBaseTestObjc.h: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkBaseTestObjc.h 3 | // 4 | // Copyright (c) 2020 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #import 26 | #import 27 | #import "ObjcBaseTestCase.h" 28 | #import "Cloudinary_Tests-Swift.h" 29 | #import 30 | 31 | typedef enum TestResourceType: NSUInteger { 32 | logo, 33 | borderCollie, 34 | docx, 35 | dog, 36 | pdf, 37 | textImage 38 | } TestResourceType; 39 | 40 | @interface NetworkBaseTestObjc: ObjcBaseTestCase 41 | 42 | @property (nonatomic, strong, nullable) CLDCloudinary* cloudinary; 43 | 44 | - (NSString* _Nonnull) getResourceNameBy:(TestResourceType)testResourceType; 45 | - (NSURL* _Nonnull) getUrlBy :(TestResourceType)testResourceType; 46 | - (NSData* _Nonnull) getDataBy :(TestResourceType)testResourceType; 47 | - (UIImage* _Nonnull) getImageBy :(TestResourceType)testResourceType; 48 | - (AVPlayerItem* _Nonnull) getVideoBy :(TestResourceType)testResourceType; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/Tests/NetworkTests/NetworkTestUtils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkTestUtils.swift 3 | // Cloudinary_Tests 4 | // 5 | // Created by Adi Mizrahi on 29/01/2025. 6 | // Copyright © 2025 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | class NetworkTestUtils { 11 | 12 | private static let environmentFolderDecoupling = "CLD_FOLDER_DECOUPLING" 13 | 14 | static func skipFolderDecouplingTest() -> Bool { 15 | guard let _ = ProcessInfo.processInfo.environment[environmentFolderDecoupling] else { 16 | return false 17 | } 18 | return true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/Tests/Resources/Docs/docx.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Docs/docx.docx -------------------------------------------------------------------------------- /Example/Tests/Resources/Docs/pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Docs/pdf.pdf -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/borderCollie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/borderCollie.jpg -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/borderCollieCropped.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/borderCollieCropped.jpg -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/borderCollieRotatedJpg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/borderCollieRotatedJpg.jpg -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/borderCollieRotatedJpgUnderIOS12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/borderCollieRotatedJpgUnderIOS12.jpg -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/borderCollieRotatedPng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/borderCollieRotatedPng.png -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/borderCollieRotatedPngUnderIOS12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/borderCollieRotatedPngUnderIOS12.png -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/logo.png -------------------------------------------------------------------------------- /Example/Tests/Resources/Images/textImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Images/textImage.jpg -------------------------------------------------------------------------------- /Example/Tests/Resources/Videos/dog.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Videos/dog.mov -------------------------------------------------------------------------------- /Example/Tests/Resources/Videos/dog.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Videos/dog.mp4 -------------------------------------------------------------------------------- /Example/Tests/Resources/Videos/dog2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudinary/cloudinary_ios/15e6d01f71705641ac07f472d9f5034ee01cc149/Example/Tests/Resources/Videos/dog2.mp4 -------------------------------------------------------------------------------- /Example/Tests/StringUtilsTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Nitzan Jaitman on 02/09/2018. 3 | // Copyright (c) 2018 Cloudinary. All rights reserved. 4 | // 5 | 6 | import Foundation 7 | import XCTest 8 | @testable import Cloudinary 9 | 10 | class StringUtilsTests: BaseTestCase { 11 | override func setUp() { 12 | super.setUp() 13 | } 14 | 15 | override func tearDown() { 16 | super.tearDown() 17 | } 18 | 19 | func testBase64Encode (){ 20 | let str = "ad?.,x09~!@!" 21 | XCTAssertEqual("YWQ/Lix4MDl+IUAh", str.cldBase64Encode()) 22 | } 23 | 24 | func testBase64UrlEncode(){ 25 | let str = "ad?.,x09~!@!" 26 | XCTAssertEqual("YWQ_Lix4MDl-IUAh", str.cldBase64UrlEncode()) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Example/Tests/TestableCloudinary.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestableCloudinary.swift 3 | // Cloudinary_Tests 4 | // 5 | // Created by Adi Mizrahi on 30/01/2025. 6 | // Copyright © 2025 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Cloudinary 10 | 11 | class TestableCloudinary { 12 | static func getNetworkCoordinator(from cloudinary: CLDCloudinary) -> AnyObject? { 13 | let mirror = Mirror(reflecting: cloudinary) 14 | for child in mirror.children { 15 | if String(describing: type(of: child.value)).contains("CLDNetworkCoordinator") { 16 | return child.value as AnyObject 17 | } 18 | } 19 | return nil 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/Tests/UIExtensions/UIBaseTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIBaseTest.swift 3 | // 4 | // Copyright (c) 2016 Cloudinary (http://cloudinary.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import XCTest 26 | import Cloudinary 27 | import UIKit 28 | 29 | class UIBaseTest: NetworkBaseTest { 30 | 31 | let url = "https://res-1.cloudinary.com/cloudinary/image/asset/dpr_2.0/logo-e0df892053afd966cc0bfe047ba93ca4.png" 32 | 33 | // MARK: - Setup 34 | 35 | override func setUp() { 36 | super.setUp() 37 | 38 | cloudinary!.enableUrlCache = false 39 | continueAfterFailure = false 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Example/WidgetUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Cloudinary (http://cloudinary.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Cloudinary", 8 | platforms: [ .iOS(.v9)], 9 | products: [ 10 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 11 | .library( 12 | name: "Cloudinary", 13 | targets: ["Cloudinary"]), 14 | ], 15 | dependencies: [ 16 | // Dependencies declare other packages that this package depends on. 17 | // .package(url: /* package url */, from: "1.0.0"), 18 | ], 19 | targets: [ 20 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 21 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 22 | .target( 23 | name: "Cloudinary", 24 | path: "Cloudinary/Classes"), 25 | ] 26 | ) 27 | -------------------------------------------------------------------------------- /Package@swift-5.3.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Cloudinary", 8 | platforms: [ .iOS(.v9)], 9 | products: [ 10 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 11 | .library( 12 | name: "Cloudinary", 13 | targets: ["Cloudinary"]), 14 | ], 15 | dependencies: [ 16 | // Dependencies declare other packages that this package depends on. 17 | // .package(url: /* package url */, from: "1.0.0"), 18 | ], 19 | targets: [ 20 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 21 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 22 | .target( 23 | name: "Cloudinary", 24 | path: "Cloudinary/Classes", 25 | resources: [ 26 | .copy("Core/Network/PrivacyInfo.xcprivacy") 27 | ] 28 | ), 29 | ] 30 | ) 31 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /tools/get_test_cloud.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function test_cloud 4 | { 5 | CLOUD_DETAILS=$(curl -X POST \-H 'Content-type:application/json' \https://sub-account-testing.cloudinary.com/create_sub_account \--data '{"prefix" : "ios-test-cloud"}') 6 | 7 | echo ${CLOUD_DETAILS} | python -c 'import json,sys;c=json.load(sys.stdin)["payload"];print("cloudinary://%s:%s@%s" % (c["cloudApiKey"], c["cloudApiSecret"], c["cloudName"]))' 8 | } 9 | 10 | test_cloud 11 | --------------------------------------------------------------------------------