diff --git a/iOS/.gitignore b/iOS/.gitignore new file mode 100644 index 0000000000..05ca299a70 --- /dev/null +++ b/iOS/.gitignore @@ -0,0 +1,42 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore +.DS_Store + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +*.xcworkspace + +## Obj-C/Swift specific +*.hmap +*.ipa + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +build +Output diff --git a/iOS/Gradio.xcodeproj/project.pbxproj b/iOS/Gradio.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..41166410c7 --- /dev/null +++ b/iOS/Gradio.xcodeproj/project.pbxproj @@ -0,0 +1,456 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + BA9C6129222F882B00B02D82 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C6128222F882B00B02D82 /* AppDelegate.swift */; }; + BA9C612B222F882B00B02D82 /* CameraInterfaceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C612A222F882B00B02D82 /* CameraInterfaceViewController.swift */; }; + BA9C612E222F882B00B02D82 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BA9C612C222F882B00B02D82 /* Main.storyboard */; }; + BA9C6130222F882C00B02D82 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BA9C612F222F882C00B02D82 /* Assets.xcassets */; }; + BA9C6133222F882C00B02D82 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BA9C6131222F882C00B02D82 /* LaunchScreen.storyboard */; }; + BA9C613B222F88B600B02D82 /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C613A222F88B600B02D82 /* CameraViewController.swift */; }; + BA9C613D222F965800B02D82 /* Camera.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C613C222F965800B02D82 /* Camera.swift */; }; + BA9C614D2231E17C00B02D82 /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C614C2231E17C00B02D82 /* UIImage+Extensions.swift */; }; + BA9C61512234667600B02D82 /* MainPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C61502234667600B02D82 /* MainPageViewController.swift */; }; + BA9C61532234755D00B02D82 /* CameraInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C61522234755D00B02D82 /* CameraInterface.swift */; }; + BA9C615522348CB900B02D82 /* TextInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C615422348CB900B02D82 /* TextInterface.swift */; }; + BA9C61582234915700B02D82 /* TextToTextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C61572234915700B02D82 /* TextToTextViewController.swift */; }; + BA9C615A2234CC9A00B02D82 /* SketchPadInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C61592234CC9A00B02D82 /* SketchPadInterface.swift */; }; + BA9C615C2234CE2700B02D82 /* SketchPadToImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C615B2234CE2700B02D82 /* SketchPadToImageViewController.swift */; }; + BA9C615E2234DB4600B02D82 /* MainTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA9C615D2234DB4600B02D82 /* MainTabBarViewController.swift */; }; + FA56A3291E9C242D9A59B355 /* Pods_Gradio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0F4AB8C8860E479D08D9B1B /* Pods_Gradio.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0478E5221F843AD4860486D2 /* Pods-Gradio.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Gradio.release.xcconfig"; path = "Pods/Target Support Files/Pods-Gradio/Pods-Gradio.release.xcconfig"; sourceTree = ""; }; + 3DD599F9F02691C494D21AD8 /* Pods-Gradio.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Gradio.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Gradio/Pods-Gradio.debug.xcconfig"; sourceTree = ""; }; + BA9C6125222F882B00B02D82 /* Gradio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Gradio.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BA9C6128222F882B00B02D82 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + BA9C612A222F882B00B02D82 /* CameraInterfaceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraInterfaceViewController.swift; sourceTree = ""; }; + BA9C612D222F882B00B02D82 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + BA9C612F222F882C00B02D82 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + BA9C6132222F882C00B02D82 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + BA9C6134222F882C00B02D82 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BA9C613A222F88B600B02D82 /* CameraViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraViewController.swift; sourceTree = ""; }; + BA9C613C222F965800B02D82 /* Camera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Camera.swift; sourceTree = ""; }; + BA9C614C2231E17C00B02D82 /* UIImage+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extensions.swift"; sourceTree = ""; }; + BA9C61502234667600B02D82 /* MainPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainPageViewController.swift; sourceTree = ""; }; + BA9C61522234755D00B02D82 /* CameraInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraInterface.swift; sourceTree = ""; }; + BA9C615422348CB900B02D82 /* TextInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextInterface.swift; sourceTree = ""; }; + BA9C61572234915700B02D82 /* TextToTextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextToTextViewController.swift; sourceTree = ""; }; + BA9C61592234CC9A00B02D82 /* SketchPadInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SketchPadInterface.swift; sourceTree = ""; }; + BA9C615B2234CE2700B02D82 /* SketchPadToImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SketchPadToImageViewController.swift; sourceTree = ""; }; + BA9C615D2234DB4600B02D82 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewController.swift; sourceTree = ""; }; + C0F4AB8C8860E479D08D9B1B /* Pods_Gradio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Gradio.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + BA9C6122222F882B00B02D82 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FA56A3291E9C242D9A59B355 /* Pods_Gradio.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5107ACADEAE2E89D7C45766D /* Frameworks */ = { + isa = PBXGroup; + children = ( + C0F4AB8C8860E479D08D9B1B /* Pods_Gradio.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 5DF7B4C66DEE1809778C41DF /* Pods */ = { + isa = PBXGroup; + children = ( + 3DD599F9F02691C494D21AD8 /* Pods-Gradio.debug.xcconfig */, + 0478E5221F843AD4860486D2 /* Pods-Gradio.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + BA9C611C222F882B00B02D82 = { + isa = PBXGroup; + children = ( + BA9C6127222F882B00B02D82 /* Gradio */, + BA9C6126222F882B00B02D82 /* Products */, + 5DF7B4C66DEE1809778C41DF /* Pods */, + 5107ACADEAE2E89D7C45766D /* Frameworks */, + ); + sourceTree = ""; + }; + BA9C6126222F882B00B02D82 /* Products */ = { + isa = PBXGroup; + children = ( + BA9C6125222F882B00B02D82 /* Gradio.app */, + ); + name = Products; + sourceTree = ""; + }; + BA9C6127222F882B00B02D82 /* Gradio */ = { + isa = PBXGroup; + children = ( + BA9C6128222F882B00B02D82 /* AppDelegate.swift */, + BA9C615B2234CE2700B02D82 /* SketchPadToImageViewController.swift */, + BA9C61572234915700B02D82 /* TextToTextViewController.swift */, + BA9C612A222F882B00B02D82 /* CameraInterfaceViewController.swift */, + BA9C613A222F88B600B02D82 /* CameraViewController.swift */, + BA9C613C222F965800B02D82 /* Camera.swift */, + BA9C612C222F882B00B02D82 /* Main.storyboard */, + BA9C612F222F882C00B02D82 /* Assets.xcassets */, + BA9C6131222F882C00B02D82 /* LaunchScreen.storyboard */, + BA9C6134222F882C00B02D82 /* Info.plist */, + BA9C614C2231E17C00B02D82 /* UIImage+Extensions.swift */, + BA9C61502234667600B02D82 /* MainPageViewController.swift */, + BA9C615D2234DB4600B02D82 /* MainTabBarViewController.swift */, + BA9C61562234904F00B02D82 /* Interfaces */, + ); + path = Gradio; + sourceTree = ""; + }; + BA9C61562234904F00B02D82 /* Interfaces */ = { + isa = PBXGroup; + children = ( + BA9C61522234755D00B02D82 /* CameraInterface.swift */, + BA9C615422348CB900B02D82 /* TextInterface.swift */, + BA9C61592234CC9A00B02D82 /* SketchPadInterface.swift */, + ); + path = Interfaces; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + BA9C6124222F882B00B02D82 /* Gradio */ = { + isa = PBXNativeTarget; + buildConfigurationList = BA9C6137222F882C00B02D82 /* Build configuration list for PBXNativeTarget "Gradio" */; + buildPhases = ( + 7FCDB3521EE8259A582818B7 /* [CP] Check Pods Manifest.lock */, + BA9C6121222F882B00B02D82 /* Sources */, + BA9C6122222F882B00B02D82 /* Frameworks */, + BA9C6123222F882B00B02D82 /* Resources */, + 1F4F92E2906F89435ADF179A /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Gradio; + productName = Gradio; + productReference = BA9C6125222F882B00B02D82 /* Gradio.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BA9C611D222F882B00B02D82 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = Gradio; + TargetAttributes = { + BA9C6124222F882B00B02D82 = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = BA9C6120222F882B00B02D82 /* Build configuration list for PBXProject "Gradio" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = BA9C611C222F882B00B02D82; + productRefGroup = BA9C6126222F882B00B02D82 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + BA9C6124222F882B00B02D82 /* Gradio */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + BA9C6123222F882B00B02D82 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BA9C6133222F882C00B02D82 /* LaunchScreen.storyboard in Resources */, + BA9C6130222F882C00B02D82 /* Assets.xcassets in Resources */, + BA9C612E222F882B00B02D82 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 1F4F92E2906F89435ADF179A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-Gradio/Pods-Gradio-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Gradio/Pods-Gradio-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 7FCDB3521EE8259A582818B7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Gradio-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + BA9C6121222F882B00B02D82 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BA9C612B222F882B00B02D82 /* CameraInterfaceViewController.swift in Sources */, + BA9C6129222F882B00B02D82 /* AppDelegate.swift in Sources */, + BA9C61532234755D00B02D82 /* CameraInterface.swift in Sources */, + BA9C615A2234CC9A00B02D82 /* SketchPadInterface.swift in Sources */, + BA9C614D2231E17C00B02D82 /* UIImage+Extensions.swift in Sources */, + BA9C615522348CB900B02D82 /* TextInterface.swift in Sources */, + BA9C613D222F965800B02D82 /* Camera.swift in Sources */, + BA9C61582234915700B02D82 /* TextToTextViewController.swift in Sources */, + BA9C615C2234CE2700B02D82 /* SketchPadToImageViewController.swift in Sources */, + BA9C615E2234DB4600B02D82 /* MainTabBarViewController.swift in Sources */, + BA9C61512234667600B02D82 /* MainPageViewController.swift in Sources */, + BA9C613B222F88B600B02D82 /* CameraViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + BA9C612C222F882B00B02D82 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + BA9C612D222F882B00B02D82 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + BA9C6131222F882C00B02D82 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + BA9C6132222F882C00B02D82 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + BA9C6135222F882C00B02D82 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + BA9C6136222F882C00B02D82 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + BA9C6138222F882C00B02D82 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3DD599F9F02691C494D21AD8 /* Pods-Gradio.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RHW8FBGSTX; + INFOPLIST_FILE = Gradio/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = app.gradio.Gradio; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + BA9C6139222F882C00B02D82 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0478E5221F843AD4860486D2 /* Pods-Gradio.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RHW8FBGSTX; + INFOPLIST_FILE = Gradio/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = app.gradio.Gradio; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + BA9C6120222F882B00B02D82 /* Build configuration list for PBXProject "Gradio" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BA9C6135222F882C00B02D82 /* Debug */, + BA9C6136222F882C00B02D82 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BA9C6137222F882C00B02D82 /* Build configuration list for PBXNativeTarget "Gradio" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BA9C6138222F882C00B02D82 /* Debug */, + BA9C6139222F882C00B02D82 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BA9C611D222F882B00B02D82 /* Project object */; +} diff --git a/iOS/Gradio/AppDelegate.swift b/iOS/Gradio/AppDelegate.swift new file mode 100644 index 0000000000..7d79017016 --- /dev/null +++ b/iOS/Gradio/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// Gradio +// +// Created by Dawood Khan on 3/5/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/iOS/Gradio/Assets.xcassets/AppIcon.appiconset/Contents.json b/iOS/Gradio/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..d8db8d65fd --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Contents.json b/iOS/Gradio/Assets.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/Contents.json new file mode 100644 index 0000000000..af8e1f2c12 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_flash_off.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_flash_off_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_flash_off_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off.png b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off.png new file mode 100644 index 0000000000..4367ecbca1 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off.png differ diff --git a/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off_2x.png b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off_2x.png new file mode 100644 index 0000000000..70ba9d28be Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off_2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off_3x.png b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off_3x.png new file mode 100644 index 0000000000..c1fb7a7882 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Flash Off Icon.imageset/ic_flash_off_3x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/Contents.json new file mode 100644 index 0000000000..82b5c2ce35 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_flash_on.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_flash_on_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_flash_on_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on.png b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on.png new file mode 100644 index 0000000000..a621a7075b Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on.png differ diff --git a/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on_2x.png b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on_2x.png new file mode 100644 index 0000000000..44a7f41189 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on_2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on_3x.png b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on_3x.png new file mode 100644 index 0000000000..8942563609 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Flash On Icon.imageset/ic_flash_on_3x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/Contents.json new file mode 100644 index 0000000000..9fd5490c6c --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_camera_front.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_camera_front_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_camera_front_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front.png b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front.png new file mode 100644 index 0000000000..85390cdb56 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front.png differ diff --git a/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front_2x.png b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front_2x.png new file mode 100644 index 0000000000..d335e3c81e Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front_2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front_3x.png b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front_3x.png new file mode 100644 index 0000000000..eee062d124 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Front Camera Icon.imageset/ic_camera_front_3x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Pencil.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Pencil.imageset/Contents.json new file mode 100644 index 0000000000..87c67b4c07 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Pencil.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "pencil.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Pencil.imageset/pencil.pdf b/iOS/Gradio/Assets.xcassets/Pencil.imageset/pencil.pdf new file mode 100644 index 0000000000..104668f2c7 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Pencil.imageset/pencil.pdf differ diff --git a/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/Contents.json new file mode 100644 index 0000000000..359e08a545 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_photo_camera.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_photo_camera_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_photo_camera_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera.png b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera.png new file mode 100644 index 0000000000..2ce3c5b7c8 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera.png differ diff --git a/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera_2x.png b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera_2x.png new file mode 100644 index 0000000000..d83d658d03 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera_2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera_3x.png b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera_3x.png new file mode 100644 index 0000000000..6125fa2b74 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Photo Camera Icon.imageset/ic_photo_camera_3x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/Contents.json new file mode 100644 index 0000000000..aaf470231e --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_camera_rear.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_camera_rear_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_camera_rear_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear.png b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear.png new file mode 100644 index 0000000000..222e9030fd Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear.png differ diff --git a/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear_2x.png b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear_2x.png new file mode 100644 index 0000000000..d24d3b7833 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear_2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear_3x.png b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear_3x.png new file mode 100644 index 0000000000..219422d6ee Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Rear Camera Icon.imageset/ic_camera_rear_3x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Contents.json new file mode 100644 index 0000000000..23eedd49e2 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Redo Button.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Redo Button@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Redo Button@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button.png b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button.png new file mode 100644 index 0000000000..69e6243a6d Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button.png differ diff --git a/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button@2x.png b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button@2x.png new file mode 100644 index 0000000000..e56367d87d Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button@2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button@3x.png b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button@3x.png new file mode 100644 index 0000000000..3ba496a046 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Redo Button.imageset/Redo Button@3x.png differ diff --git a/iOS/Gradio/Assets.xcassets/T.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/T.imageset/Contents.json new file mode 100644 index 0000000000..bb4a1d947b --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/T.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "letter-t-icon-png-24.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/T.imageset/letter-t-icon-png-24.pdf b/iOS/Gradio/Assets.xcassets/T.imageset/letter-t-icon-png-24.pdf new file mode 100644 index 0000000000..7c567463de Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/T.imageset/letter-t-icon-png-24.pdf differ diff --git a/iOS/Gradio/Assets.xcassets/TapForCamera.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/TapForCamera.imageset/Contents.json new file mode 100644 index 0000000000..9237614e84 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/TapForCamera.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "TapForCamera.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/TapForCamera.imageset/TapForCamera.pdf b/iOS/Gradio/Assets.xcassets/TapForCamera.imageset/TapForCamera.pdf new file mode 100644 index 0000000000..8c6f44abc8 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/TapForCamera.imageset/TapForCamera.pdf differ diff --git a/iOS/Gradio/Assets.xcassets/Title Image.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Title Image.imageset/Contents.json new file mode 100644 index 0000000000..a87a580743 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Title Image.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Screen Shot 2019-03-09 at 7.56.56 PM.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Title Image.imageset/Screen Shot 2019-03-09 at 7.56.56 PM.png b/iOS/Gradio/Assets.xcassets/Title Image.imageset/Screen Shot 2019-03-09 at 7.56.56 PM.png new file mode 100644 index 0000000000..5fab0322a3 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Title Image.imageset/Screen Shot 2019-03-09 at 7.56.56 PM.png differ diff --git a/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/Contents.json new file mode 100644 index 0000000000..4c325a4f49 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ic_videocam.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "ic_videocam_2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "ic_videocam_3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam.png b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam.png new file mode 100644 index 0000000000..0722a69290 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam.png differ diff --git a/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam_2x.png b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam_2x.png new file mode 100644 index 0000000000..b0a3b44d15 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam_2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam_3x.png b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam_3x.png new file mode 100644 index 0000000000..0039e804eb Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/Video Camera Icon.imageset/ic_videocam_3x.png differ diff --git a/iOS/Gradio/Assets.xcassets/X Button.imageset/Contents.json b/iOS/Gradio/Assets.xcassets/X Button.imageset/Contents.json new file mode 100644 index 0000000000..8aeb47dff8 --- /dev/null +++ b/iOS/Gradio/Assets.xcassets/X Button.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "X Button.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "X Button@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "X Button@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button.png b/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button.png new file mode 100644 index 0000000000..54f1403d87 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button.png differ diff --git a/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button@2x.png b/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button@2x.png new file mode 100644 index 0000000000..dd92625a18 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button@2x.png differ diff --git a/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button@3x.png b/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button@3x.png new file mode 100644 index 0000000000..6818b173a1 Binary files /dev/null and b/iOS/Gradio/Assets.xcassets/X Button.imageset/X Button@3x.png differ diff --git a/iOS/Gradio/Base.lproj/LaunchScreen.storyboard b/iOS/Gradio/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000..bfa3612941 --- /dev/null +++ b/iOS/Gradio/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/Gradio/Base.lproj/Main.storyboard b/iOS/Gradio/Base.lproj/Main.storyboard new file mode 100644 index 0000000000..00c6f0a33f --- /dev/null +++ b/iOS/Gradio/Base.lproj/Main.storyboard @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/Gradio/Camera.swift b/iOS/Gradio/Camera.swift new file mode 100644 index 0000000000..6fa216a0f7 --- /dev/null +++ b/iOS/Gradio/Camera.swift @@ -0,0 +1,222 @@ +// +// Camera.swift +// Gradio +// +// Created by Dawood Khan on 3/5/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit +import AVFoundation + +class Camera: NSObject { + var captureSession: AVCaptureSession? + + var currentCameraPosition: CameraPosition? + + var frontCamera: AVCaptureDevice? + var frontCameraInput: AVCaptureDeviceInput? + + var photoOutput: AVCapturePhotoOutput? + + var rearCamera: AVCaptureDevice? + var rearCameraInput: AVCaptureDeviceInput? + + var previewLayer: AVCaptureVideoPreviewLayer? + + var flashMode = AVCaptureDevice.FlashMode.off + var photoCaptureCompletionBlock: ((UIImage?, Error?) -> Void)? +} + +extension Camera { + func prepare(completionHandler: @escaping (Error?) -> Void) { + func createCaptureSession() { + self.captureSession = AVCaptureSession() + } + + func configureCaptureDevices() throws { + + let session = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .unspecified) + let cameras = session.devices.compactMap { $0 } + guard !cameras.isEmpty else { throw CameraError.noCamerasAvailable } + + for camera in cameras { + if camera.position == .front { + self.frontCamera = camera + } + + if camera.position == .back { + self.rearCamera = camera + + try camera.lockForConfiguration() + camera.focusMode = .continuousAutoFocus + camera.unlockForConfiguration() + } + } + } + + func configureDeviceInputs() throws { + guard let captureSession = self.captureSession else { throw CameraError.captureSessionIsMissing } + + if let rearCamera = self.rearCamera { + self.rearCameraInput = try AVCaptureDeviceInput(device: rearCamera) + + if captureSession.canAddInput(self.rearCameraInput!) { captureSession.addInput(self.rearCameraInput!) } + + self.currentCameraPosition = .rear + } + + else if let frontCamera = self.frontCamera { + self.frontCameraInput = try AVCaptureDeviceInput(device: frontCamera) + + if captureSession.canAddInput(self.frontCameraInput!) { captureSession.addInput(self.frontCameraInput!) } + else { throw CameraError.inputsAreInvalid } + + self.currentCameraPosition = .front + } + + else { throw CameraError.noCamerasAvailable } + } + + func configurePhotoOutput() throws { + guard let captureSession = self.captureSession else { throw CameraError.captureSessionIsMissing } + + self.photoOutput = AVCapturePhotoOutput() + self.photoOutput!.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])], completionHandler: nil) + + if captureSession.canAddOutput(self.photoOutput!) { captureSession.addOutput(self.photoOutput!) } + captureSession.startRunning() + } + + DispatchQueue(label: "prepare").async { + do { + createCaptureSession() + try configureCaptureDevices() + try configureDeviceInputs() + try configurePhotoOutput() + } + + catch { + DispatchQueue.main.async { + completionHandler(error) + } + + return + } + + DispatchQueue.main.async { + completionHandler(nil) + } + } + } + + func displayPreview(on view: UIView) throws { + guard let captureSession = self.captureSession, captureSession.isRunning else { throw CameraError.captureSessionIsMissing } + + self.previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) + self.previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill + self.previewLayer?.connection?.videoOrientation = .portrait + + view.layer.insertSublayer(self.previewLayer!, at: 0) + self.previewLayer?.frame = view.frame + } + + func switchCameras() throws { + guard let currentCameraPosition = currentCameraPosition, let captureSession = self.captureSession, captureSession.isRunning else { throw CameraError.captureSessionIsMissing } + + captureSession.beginConfiguration() + + func switchToFrontCamera() throws { + + guard let rearCameraInput = self.rearCameraInput, captureSession.inputs.contains(rearCameraInput), + let frontCamera = self.frontCamera else { throw CameraError.invalidOperation } + + self.frontCameraInput = try AVCaptureDeviceInput(device: frontCamera) + + captureSession.removeInput(rearCameraInput) + + if captureSession.canAddInput(self.frontCameraInput!) { + captureSession.addInput(self.frontCameraInput!) + + self.currentCameraPosition = .front + } + + else { + throw CameraError.invalidOperation + } + } + + func switchToRearCamera() throws { + + guard let frontCameraInput = self.frontCameraInput, captureSession.inputs.contains(frontCameraInput), + let rearCamera = self.rearCamera else { throw CameraError.invalidOperation } + + self.rearCameraInput = try AVCaptureDeviceInput(device: rearCamera) + + captureSession.removeInput(frontCameraInput) + + if captureSession.canAddInput(self.rearCameraInput!) { + captureSession.addInput(self.rearCameraInput!) + + self.currentCameraPosition = .rear + } + + else { throw CameraError.invalidOperation } + } + + switch currentCameraPosition { + case .front: + try switchToRearCamera() + + case .rear: + try switchToFrontCamera() + } + + captureSession.commitConfiguration() + } + + func captureImage(completion: @escaping (UIImage?, Error?) -> Void) { + guard let captureSession = captureSession, captureSession.isRunning else { completion(nil, CameraError.captureSessionIsMissing); return } + + let settings = AVCapturePhotoSettings() + settings.flashMode = self.flashMode + + self.photoOutput?.capturePhoto(with: settings, delegate: self) + self.photoCaptureCompletionBlock = completion + } + +} + +extension Camera: AVCapturePhotoCaptureDelegate { + public func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?, + resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Swift.Error?) { + if let error = error { self.photoCaptureCompletionBlock?(nil, error) } + + else if let buffer = photoSampleBuffer, let data = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: buffer, previewPhotoSampleBuffer: nil), + let image = UIImage(data: data) { + + self.photoCaptureCompletionBlock?(image, nil) + } + + else { + self.photoCaptureCompletionBlock?(nil, CameraError.unknown) + } + } +} + +extension Camera { + enum CameraError: Swift.Error { + case captureSessionAlreadyRunning + case captureSessionIsMissing + case inputsAreInvalid + case invalidOperation + case noCamerasAvailable + case unknown + } + + public enum CameraPosition { + case front + case rear + } +} + diff --git a/iOS/Gradio/CameraInterfaceViewController.swift b/iOS/Gradio/CameraInterfaceViewController.swift new file mode 100644 index 0000000000..fb00f47bd9 --- /dev/null +++ b/iOS/Gradio/CameraInterfaceViewController.swift @@ -0,0 +1,120 @@ +// +// CameraInterfaceViewController.swift +// Gradio +// +// Created by Dawood Khan on 3/5/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit +import Photos +import Starscream + +class CameraInterfaceViewController: UIViewController, WebSocketDelegate { + + var titleImageView: UIImageView = UIImageView() + var cameraViewController: CameraViewController? + var preview: UIImageView = UIImageView() + var outputTextView: UITextView = UITextView() + var socket: WebSocket = WebSocket(url: URL(string: "ws://c3f3ea66.ngrok.io")!) + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = UIColor.white + + titleImageView.image = UIImage(named: "Title Image") + titleImageView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(titleImageView) + titleImageView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10.0).isActive = true + titleImageView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5).isActive = true + titleImageView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.08).isActive = true + titleImageView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true + + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(stackView) + stackView.distribution = .equalSpacing + stackView.alignment = .fill + stackView.axis = .vertical + stackView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.8).isActive = true + stackView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.8).isActive = true + stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true + stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true + + let tapForCameraImage = UIImage(named: "TapForCamera") + preview = UIImageView(image: tapForCameraImage) + preview.translatesAutoresizingMaskIntoConstraints = false + preview.contentMode = .scaleAspectFit + stackView.addArrangedSubview(preview) + preview.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.45).isActive = true + preview.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true + + outputTextView = UITextView() + outputTextView.translatesAutoresizingMaskIntoConstraints = false + outputTextView.backgroundColor = UIColor(red: 0.72, green: 0.72, blue: 0.72, alpha: 1.0) + outputTextView.isEditable = false + outputTextView.text = "OUTPUT" + outputTextView.textColor = UIColor.darkGray + outputTextView.font = UIFont(name: "ArialMT", size: 24) + stackView.addArrangedSubview(outputTextView) + outputTextView.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.45).isActive = true + outputTextView.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true + + let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) + cameraViewController = storyBoard.instantiateViewController(withIdentifier: "CameraViewController") as? CameraViewController + + let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:))) + preview.isUserInteractionEnabled = true + preview.addGestureRecognizer(tapGestureRecognizer) + + updatePreviewWithCapturedImage() + setupWebSocket() + } + + @objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) { +// let cameraInterfaceViewController = CameraInterfaceViewController() +// self.navigationController?.pushViewController(cameraInterfaceViewController, animated: true) + guard let cameraInterfaceViewController = cameraViewController else { return } + self.present(cameraInterfaceViewController, animated: true, completion: nil) + } + + func updatePreviewWithCapturedImage() { + guard let cameraViewController = cameraViewController else { return } + cameraViewController.imageCaptureCompletionBlock = { image in + DispatchQueue.main.async { + self.preview.image = image + self.preview.setNeedsDisplay() + self.preview.setNeedsLayout() + } + let resizedImage = image.resizeImage(targetSize: CGSize(width: 360, height: 360)) + let imageData: NSData = resizedImage.pngData()! as NSData + let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters) + let fullBase64String = "data:image/png;base64,\(strBase64))" + self.socket.write(string: fullBase64String) + + } + } + + func setupWebSocket() { + socket.delegate = self + socket.connect() + } + + func websocketDidConnect(socket: WebSocketClient) { + print("Web Socket Connected!") + } + + func websocketDidDisconnect(socket: WebSocketClient, error: Error?) { + print("Web Socket Disconnected: ", error.debugDescription) + } + + func websocketDidReceiveMessage(socket: WebSocketClient, text: String) { + print("Web Socket received message!") + outputTextView.text = "Text Recieved: " + text + } + + func websocketDidReceiveData(socket: WebSocketClient, data: Data) { + print("Web Socket received data!") + outputTextView.text = "Data Recieved: " + data.base64EncodedString() + } +} diff --git a/iOS/Gradio/CameraViewController.swift b/iOS/Gradio/CameraViewController.swift new file mode 100644 index 0000000000..a58a1c908e --- /dev/null +++ b/iOS/Gradio/CameraViewController.swift @@ -0,0 +1,129 @@ +// +// CameraViewController.swift +// Gradio +// +// Created by Dawood Khan on 3/5/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit +import Photos + +class CameraViewController: UIViewController { + + @IBOutlet fileprivate var captureButton: UIButton! + + ///Displays a preview of the video output generated by the device's cameras. + @IBOutlet fileprivate var capturePreviewView: UIView! + + ///Allows the user to put the camera in photo mode. + @IBOutlet fileprivate var photoModeButton: UIButton! + @IBOutlet fileprivate var toggleCameraButton: UIButton! + @IBOutlet fileprivate var toggleFlashButton: UIButton! + + ///Allows the user to put the camera in video mode. + @IBOutlet fileprivate var videoModeButton: UIButton! + @IBOutlet var xButton: UIButton! + + let camera = Camera() + + var imageCaptureCompletionBlock: ((_ image: UIImage) -> ())? + + override var prefersStatusBarHidden: Bool { return true } +} + +extension CameraViewController { + override func viewDidLoad() { + if AVCaptureDevice.authorizationStatus(for: AVMediaType.video) == AVAuthorizationStatus.authorized { + configurecamera() + } else { + AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (granted: Bool) -> Void in + if granted == true { + self.configurecamera() + } else { + print("User rejected camera access") + } + }) + } + + func styleCaptureButton() { + captureButton.layer.borderColor = UIColor.black.cgColor + captureButton.layer.borderWidth = 2 + + captureButton.layer.cornerRadius = min(captureButton.frame.width, captureButton.frame.height) / 2 + } + + styleCaptureButton() + + } + + func configurecamera() { + camera.prepare {(error) in + if let error = error { + print(error) + } + + try? self.camera.displayPreview(on: self.capturePreviewView) + } + } +} + +extension CameraViewController { + + + @IBAction func toggleFlash(_ sender: UIButton) { + if camera.flashMode == .on { + camera.flashMode = .off + toggleFlashButton.setImage(#imageLiteral(resourceName: "Flash Off Icon"), for: .normal) + } + + else { + camera.flashMode = .on + toggleFlashButton.setImage(#imageLiteral(resourceName: "Flash On Icon"), for: .normal) + } + } + + @IBAction func switchCameras(_ sender: UIButton) { + do { + try camera.switchCameras() + } + + catch { + print(error) + } + + switch camera.currentCameraPosition { + case .some(.front): + toggleCameraButton.setImage(#imageLiteral(resourceName: "Front Camera Icon"), for: .normal) + + case .some(.rear): + toggleCameraButton.setImage(#imageLiteral(resourceName: "Rear Camera Icon"), for: .normal) + + case .none: + return + } + } + //next do completion block for view controller class + @IBAction func captureImage(_ sender: UIButton) { + camera.captureImage {(image, error) in + guard let image = image else { + print(error ?? "Image capture error") + return + } + + self.imageCaptureCompletionBlock?(image) + + try? PHPhotoLibrary.shared().performChangesAndWait { + PHAssetChangeRequest.creationRequestForAsset(from: image) + } +// self.captureButton.setImage(UIImage(named: "Redo Button"), for: .normal) + self.dismiss(animated: false, completion: { + //dismissed + }) + } + } + + @IBAction func xButtonPressed(_ sender: Any) { + self.dismiss(animated: true) + } +} diff --git a/iOS/Gradio/Info.plist b/iOS/Gradio/Info.plist new file mode 100644 index 0000000000..cc0396af14 --- /dev/null +++ b/iOS/Gradio/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSCameraUsageDescription + $(PRODUCT_NAME) camera use + NSPhotoLibraryUsageDescription + $(PRODUCT_NAME) photo use + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/iOS/Gradio/Interfaces/CameraInterface.swift b/iOS/Gradio/Interfaces/CameraInterface.swift new file mode 100644 index 0000000000..5ae0e1ab02 --- /dev/null +++ b/iOS/Gradio/Interfaces/CameraInterface.swift @@ -0,0 +1,15 @@ +// +// CameraInterface.swift +// Gradio +// +// Created by Dawood Khan on 3/9/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +class CameraInterface: UIView { + + + +} diff --git a/iOS/Gradio/Interfaces/SketchPadInterface.swift b/iOS/Gradio/Interfaces/SketchPadInterface.swift new file mode 100644 index 0000000000..9742f5c26b --- /dev/null +++ b/iOS/Gradio/Interfaces/SketchPadInterface.swift @@ -0,0 +1,121 @@ +// +// SketchPadInterface.swift +// Gradio +// +// Created by Dawood Khan on 3/9/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +class SketchPadInterface: UIView { + + let interfaceType: InterfaceType? + var mainImageView: UIImageView = UIImageView() + var tempImageView: UIImageView = UIImageView() + + var lastPoint = CGPoint.zero + var color = UIColor.black + var brushWidth: CGFloat = 10.0 + var opacity: CGFloat = 1.0 + var swiped = false + + init(interfaceType: InterfaceType) { + self.interfaceType = interfaceType + super.init(frame: CGRect.zero) + setupView() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func setupView() { + self.addSubview(mainImageView) +// self.isExclusiveTouch = true + mainImageView.translatesAutoresizingMaskIntoConstraints = false + mainImageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true + mainImageView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true + mainImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true + mainImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true + + self.addSubview(tempImageView) + tempImageView.translatesAutoresizingMaskIntoConstraints = false + tempImageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true + tempImageView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true + tempImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true + tempImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true + + } + + func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) { + UIGraphicsBeginImageContext(self.frame.size) + guard let context = UIGraphicsGetCurrentContext() else { + return + } + tempImageView.image?.draw(in: self.bounds) + + context.move(to: fromPoint) + context.addLine(to: toPoint) + + context.setLineCap(.round) + context.setBlendMode(.normal) + context.setLineWidth(brushWidth) + context.setStrokeColor(color.cgColor) + + context.strokePath() + + tempImageView.image = UIGraphicsGetImageFromCurrentImageContext() + tempImageView.alpha = opacity + + UIGraphicsEndImageContext() + } + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + guard let touch = touches.first else { + return + } + swiped = false + lastPoint = touch.location(in: self) + } + + override func touchesMoved(_ touches: Set, with event: UIEvent?) { + guard let touch = touches.first else { + return + } + swiped = true + let currentPoint = touch.location(in: self) + drawLine(from: lastPoint, to: currentPoint) + + lastPoint = currentPoint + } + + override func touchesEnded(_ touches: Set, with event: UIEvent?) { + if !swiped { + // draw a single point + drawLine(from: lastPoint, to: lastPoint) + } + + // Merge tempImageView into mainImageView + UIGraphicsBeginImageContext(mainImageView.frame.size) + mainImageView.image?.draw(in: self.bounds, blendMode: .normal, alpha: 1.0) + tempImageView.image?.draw(in: self.bounds, blendMode: .normal, alpha: opacity) + mainImageView.image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + tempImageView.image = nil + } +} + +// MARK: - SettingsViewControllerDelegate + +//extension SketchPadInterface: SettingsViewControllerDelegate { +// func settingsViewControllerFinished(_ settingsViewController: SettingsViewController) { +// brushWidth = settingsViewController.brush +// opacity = settingsViewController.opacity +// color = UIColor(red: settingsViewController.red, +// green: settingsViewController.green, +// blue: settingsViewController.blue, +// alpha: opacity) +// dismiss(animated: true) +// } diff --git a/iOS/Gradio/Interfaces/TextInterface.swift b/iOS/Gradio/Interfaces/TextInterface.swift new file mode 100644 index 0000000000..20523828b3 --- /dev/null +++ b/iOS/Gradio/Interfaces/TextInterface.swift @@ -0,0 +1,56 @@ +// +// TextInterface.swift +// Gradio +// +// Created by Dawood Khan on 3/9/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +enum InterfaceType: String { + case Input + case Output +} + +class TextInterface: UIView { + + let interfaceType: InterfaceType? + var textView: UITextView = UITextView() + + init(interfaceType: InterfaceType) { + self.interfaceType = interfaceType + super.init(frame: CGRect.zero) + setupView() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func setupView() { +// var textView: UITextView = UITextView() + textView = UITextView() + textView.translatesAutoresizingMaskIntoConstraints = false + textView.backgroundColor = UIColor(red: 0.72, green: 0.72, blue: 0.72, alpha: 1.0) + textView.textColor = UIColor.darkGray + textView.font = UIFont(name: "ArialMT", size: 24) + guard let interfaceType = interfaceType else { return } + if interfaceType == InterfaceType.Input { + textView.isEditable = true + } else { + textView.isEditable = false + } + textView.text = "\(interfaceType)".uppercased() + self.addSubview(textView) + textView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true + textView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true + textView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true + textView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true + } + + func setText(text: String) { + textView.text = text + } + +} diff --git a/iOS/Gradio/MainPageViewController.swift b/iOS/Gradio/MainPageViewController.swift new file mode 100644 index 0000000000..2e27304e1a --- /dev/null +++ b/iOS/Gradio/MainPageViewController.swift @@ -0,0 +1,75 @@ +// +// MainPageViewController.swift +// Gradio +// +// Created by Dawood Khan on 3/9/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +class MainPageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource { + + var pageControl = UIPageControl() + + lazy var pages: [UIViewController] = { + var pages = [UIViewController]() + let firstVC = CameraInterfaceViewController() + let secondVC = TextToTextViewController() + let thirdVC = SketchPadToImageViewController() + pages.append(firstVC) + pages.append(secondVC) + pages.append(thirdVC) + return pages + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.dataSource = self + self.delegate = self + if let firstVC = pages.first { + setViewControllers([firstVC], direction: .forward, animated: true, completion: nil) + } + configurePageControl() + } + + func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = pages.index(of: viewController) else { return nil } + let previousIndex = viewControllerIndex - 1 + guard previousIndex >= 0 else { return pages.last } + guard pages.count > previousIndex else { return nil } + return pages[previousIndex] + } + + func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { + guard let viewControllerIndex = pages.index(of: viewController) else { return nil } + let nextIndex = viewControllerIndex + 1 + guard nextIndex < pages.count else { return pages.first } + guard pages.count > nextIndex else { return nil } + return pages[nextIndex] + } + + func configurePageControl() { + pageControl = UIPageControl(frame: CGRect(x: 0,y: UIScreen.main.bounds.maxY - 50,width: UIScreen.main.bounds.width,height: 50)) + self.pageControl.numberOfPages = pages.count + self.pageControl.currentPage = 0 + self.pageControl.alpha = 0.5 + self.pageControl.tintColor = UIColor.black + self.pageControl.pageIndicatorTintColor = UIColor.lightGray + self.pageControl.currentPageIndicatorTintColor = UIColor.black + self.view.addSubview(pageControl) + } + + func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int { + return pages.count + } + + func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int { + return 0 + } + + func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { + let pageContentViewController = pageViewController.viewControllers![0] + self.pageControl.currentPage = pages.index(of: pageContentViewController)! + } +} diff --git a/iOS/Gradio/MainTabBarViewController.swift b/iOS/Gradio/MainTabBarViewController.swift new file mode 100644 index 0000000000..49d5e06f3d --- /dev/null +++ b/iOS/Gradio/MainTabBarViewController.swift @@ -0,0 +1,41 @@ +// +// MainTabBarViewController.swift +// Gradio +// +// Created by Dawood Khan on 3/9/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate { + + override func viewDidLoad() { + super.viewDidLoad() + self.delegate = self + // Do any additional setup after loading the view. + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + let firstVC = CameraInterfaceViewController() + let firstIcon = UITabBarItem(title: "Camera", image: UIImage(named: "Photo Camera Icon"), tag: 1) + firstVC.tabBarItem = firstIcon + + let secondVC = TextToTextViewController() + let secondIcon = UITabBarItem(title: "Text", image: UIImage(named: "T"), tag: 2) + secondVC.tabBarItem = secondIcon + + let thirdVC = SketchPadToImageViewController() + let thirdIcon = UITabBarItem(title: "Sketch", image: UIImage(named: "Pencil"), tag: 2) + thirdVC.tabBarItem = thirdIcon + + let controllers = [firstVC, secondVC, thirdVC] + self.viewControllers = controllers + } + + func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { + return true; + } + +} diff --git a/iOS/Gradio/SketchPadToImageViewController.swift b/iOS/Gradio/SketchPadToImageViewController.swift new file mode 100644 index 0000000000..42579b0ab2 --- /dev/null +++ b/iOS/Gradio/SketchPadToImageViewController.swift @@ -0,0 +1,61 @@ +// +// SketchPadToImageViewController.swift +// Gradio +// +// Created by Dawood Khan on 3/9/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +class SketchPadToImageViewController: UIViewController, UIGestureRecognizerDelegate { + + var titleImageView: UIImageView = UIImageView() + var sketchPadInput: SketchPadInterface = SketchPadInterface(interfaceType: InterfaceType.Input) + var outputImage: UIImageView = UIImageView() + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = UIColor.white + titleImageView.image = UIImage(named: "Title Image") + titleImageView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(titleImageView) + titleImageView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10.0).isActive = true + titleImageView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5).isActive = true + titleImageView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.08).isActive = true + titleImageView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true + + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(stackView) + stackView.distribution = .equalSpacing + stackView.alignment = .fill + stackView.axis = .vertical + stackView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.8).isActive = true + stackView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.8).isActive = true + stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true + stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true + + sketchPadInput.translatesAutoresizingMaskIntoConstraints = false + sketchPadInput.backgroundColor = UIColor(red: 0.72, green: 0.72, blue: 0.72, alpha: 1.0) + stackView.addArrangedSubview(sketchPadInput) + sketchPadInput.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.45).isActive = true + sketchPadInput.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true + + outputImage.translatesAutoresizingMaskIntoConstraints = false + outputImage.backgroundColor = UIColor(red: 0.72, green: 0.72, blue: 0.72, alpha: 1.0) + stackView.addArrangedSubview(outputImage) + outputImage.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.45).isActive = true + outputImage.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true + + // let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) + // cameraViewController = storyBoard.instantiateViewController(withIdentifier: "CameraViewController") as? CameraViewController + // + // let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:))) + // preview.isUserInteractionEnabled = true + // preview.addGestureRecognizer(tapGestureRecognizer) + // + // updatePreviewWithCapturedImage() + // setupWebSocket() + } +} diff --git a/iOS/Gradio/TextToTextViewController.swift b/iOS/Gradio/TextToTextViewController.swift new file mode 100644 index 0000000000..e2330d88a8 --- /dev/null +++ b/iOS/Gradio/TextToTextViewController.swift @@ -0,0 +1,94 @@ +// +// TextToTextViewController.swift +// Gradio +// +// Created by Dawood Khan on 3/9/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit +import Starscream + +class TextToTextViewController: UIViewController, WebSocketDelegate { + + var titleImageView: UIImageView = UIImageView() + var inputTextView: TextInterface = TextInterface(interfaceType: InterfaceType.Input) + var outputTextView: TextInterface = TextInterface(interfaceType: InterfaceType.Output) + var socket: WebSocket = WebSocket(url: URL(string: "ws://c3f3ea66.ngrok.io")!) + + override func viewDidLoad() { + super.viewDidLoad() + self.view.backgroundColor = UIColor.white + + let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) + self.view.addGestureRecognizer(tap) + + titleImageView.image = UIImage(named: "Title Image") + titleImageView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(titleImageView) + titleImageView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10.0).isActive = true + titleImageView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5).isActive = true + titleImageView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.08).isActive = true + titleImageView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true + + let stackView = UIStackView() + stackView.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(stackView) + stackView.distribution = .equalSpacing + stackView.alignment = .fill + stackView.axis = .vertical + stackView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.8).isActive = true + stackView.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.8).isActive = true + stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true + stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true + + inputTextView.translatesAutoresizingMaskIntoConstraints = false + inputTextView.backgroundColor = UIColor(red: 0.72, green: 0.72, blue: 0.72, alpha: 1.0) + stackView.addArrangedSubview(inputTextView) + inputTextView.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.45).isActive = true + inputTextView.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true + + outputTextView.translatesAutoresizingMaskIntoConstraints = false + outputTextView.backgroundColor = UIColor(red: 0.72, green: 0.72, blue: 0.72, alpha: 1.0) + stackView.addArrangedSubview(outputTextView) + outputTextView.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.45).isActive = true + outputTextView.widthAnchor.constraint(equalTo: stackView.widthAnchor).isActive = true + +// let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) +// cameraViewController = storyBoard.instantiateViewController(withIdentifier: "CameraViewController") as? CameraViewController +// +// let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:))) +// preview.isUserInteractionEnabled = true +// preview.addGestureRecognizer(tapGestureRecognizer) +// +// updatePreviewWithCapturedImage() + setupWebSocket() + } + + @objc func dismissKeyboard() { + view.endEditing(true) + } + + func setupWebSocket() { + socket.delegate = self + socket.connect() + } + + func websocketDidConnect(socket: WebSocketClient) { + print("Web Socket Connected!") + } + + func websocketDidDisconnect(socket: WebSocketClient, error: Error?) { + print("Web Socket Disconnected: ", error.debugDescription) + } + + func websocketDidReceiveMessage(socket: WebSocketClient, text: String) { + print("Web Socket received message!") + outputTextView.setText(text: text) + } + + func websocketDidReceiveData(socket: WebSocketClient, data: Data) { + print("Web Socket received data!") + outputTextView.setText(text: data.base64EncodedString()) + } +} diff --git a/iOS/Gradio/UIImage+Extensions.swift b/iOS/Gradio/UIImage+Extensions.swift new file mode 100644 index 0000000000..c9aaa6412c --- /dev/null +++ b/iOS/Gradio/UIImage+Extensions.swift @@ -0,0 +1,77 @@ +// +// UIImage+Extensions.swift +// Gradio +// +// Created by Dawood Khan on 3/7/19. +// Copyright © 2019 Gradio. All rights reserved. +// + +import UIKit + +extension UIImage { +// func resizeImage(_ dimension: CGFloat, opaque: Bool, contentMode: UIView.ContentMode = .scaleAspectFit) -> UIImage { +// var width: CGFloat +// var height: CGFloat +// var newImage: UIImage +// +// let size = self.size +// let aspectRatio = size.width/size.height +// +// switch contentMode { +// case .scaleAspectFit: +// if aspectRatio > 1 { // Landscape image +// width = dimension +// height = dimension / aspectRatio +// } else { // Portrait image +// height = dimension +// width = dimension * aspectRatio +// } +// +// default: +// fatalError("UIIMage.resizeToFit(): FATAL: Unimplemented ContentMode") +// } +// +// if #available(iOS 10.0, *) { +// let renderFormat = UIGraphicsImageRendererFormat.default() +// renderFormat.opaque = opaque +// let renderer = UIGraphicsImageRenderer(size: CGSize(width: width, height: height), format: renderFormat) +// newImage = renderer.image { +// (context) in +// self.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) +// } +// } else { +// UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), opaque, 0) +// self.draw(in: CGRect(x: 0, y: 0, width: width, height: height)) +// newImage = UIGraphicsGetImageFromCurrentImageContext()! +// UIGraphicsEndImageContext() +// } +// +// return newImage +// } + + func resizeImage(targetSize: CGSize) -> UIImage { + let size = self.size + + let widthRatio = targetSize.width / size.width + let heightRatio = targetSize.height / size.height + + // Figure out what our orientation is, and use that to form the rectangle + var newSize: CGSize + if(widthRatio > heightRatio) { + newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) + } else { + newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) + } + + // This is the rect that we've calculated out and this is what is actually used below + let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) + + // Actually do the resizing to the rect using the ImageContext stuff + UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) + self.draw(in: rect) + let newImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return newImage! + } +} diff --git a/iOS/Podfile b/iOS/Podfile new file mode 100644 index 0000000000..d0fc19f57a --- /dev/null +++ b/iOS/Podfile @@ -0,0 +1,11 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'Gradio' do + # Comment the next line if you're not using Swift and don't want to use dynamic frameworks + use_frameworks! + + # Pods for Gradio + pod 'Starscream', '~> 3.0.2' + +end diff --git a/iOS/Podfile.lock b/iOS/Podfile.lock new file mode 100644 index 0000000000..b32e764d41 --- /dev/null +++ b/iOS/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - Starscream (3.0.6) + +DEPENDENCIES: + - Starscream (~> 3.0.2) + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Starscream + +SPEC CHECKSUMS: + Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5 + +PODFILE CHECKSUM: 2f2c34c8ff3ab88ffa46fb47cbe80129af8b19a3 + +COCOAPODS: 1.5.3