├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .slather.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── Package.swift ├── Podfile ├── Podfile.lock ├── Pods ├── Local Podspecs │ └── SwiftyMessenger.podspec.json ├── Manifest.lock ├── Pods.xcodeproj │ └── project.pbxproj └── Target Support Files │ ├── Pods-Sample Today Extension │ ├── Info.plist │ ├── Pods-Sample Today Extension-Info.plist │ ├── Pods-Sample Today Extension-acknowledgements.markdown │ ├── Pods-Sample Today Extension-acknowledgements.plist │ ├── Pods-Sample Today Extension-dummy.m │ ├── Pods-Sample Today Extension-resources.sh │ ├── Pods-Sample Today Extension-umbrella.h │ ├── Pods-Sample Today Extension.debug.xcconfig │ ├── Pods-Sample Today Extension.modulemap │ └── Pods-Sample Today Extension.release.xcconfig │ ├── Pods-Sample WatchOS App Extension │ ├── Info.plist │ ├── Pods-Sample WatchOS App Extension-Info.plist │ ├── Pods-Sample WatchOS App Extension-acknowledgements.markdown │ ├── Pods-Sample WatchOS App Extension-acknowledgements.plist │ ├── Pods-Sample WatchOS App Extension-dummy.m │ ├── Pods-Sample WatchOS App Extension-frameworks-Debug-input-files.xcfilelist │ ├── Pods-Sample WatchOS App Extension-frameworks-Debug-output-files.xcfilelist │ ├── Pods-Sample WatchOS App Extension-frameworks-Release-input-files.xcfilelist │ ├── Pods-Sample WatchOS App Extension-frameworks-Release-output-files.xcfilelist │ ├── Pods-Sample WatchOS App Extension-frameworks.sh │ ├── Pods-Sample WatchOS App Extension-resources.sh │ ├── Pods-Sample WatchOS App Extension-umbrella.h │ ├── Pods-Sample WatchOS App Extension.debug.xcconfig │ ├── Pods-Sample WatchOS App Extension.modulemap │ └── Pods-Sample WatchOS App Extension.release.xcconfig │ ├── Pods-Sample iOS App │ ├── Info.plist │ ├── Pods-Sample iOS App-Info.plist │ ├── Pods-Sample iOS App-acknowledgements.markdown │ ├── Pods-Sample iOS App-acknowledgements.plist │ ├── Pods-Sample iOS App-dummy.m │ ├── Pods-Sample iOS App-frameworks-Debug-input-files.xcfilelist │ ├── Pods-Sample iOS App-frameworks-Debug-output-files.xcfilelist │ ├── Pods-Sample iOS App-frameworks-Release-input-files.xcfilelist │ ├── Pods-Sample iOS App-frameworks-Release-output-files.xcfilelist │ ├── Pods-Sample iOS App-frameworks.sh │ ├── Pods-Sample iOS App-resources.sh │ ├── Pods-Sample iOS App-umbrella.h │ ├── Pods-Sample iOS App.debug.xcconfig │ ├── Pods-Sample iOS App.modulemap │ └── Pods-Sample iOS App.release.xcconfig │ ├── SwiftyMessenger-iOS │ ├── Info.plist │ ├── SwiftyMessenger-iOS-Info.plist │ ├── SwiftyMessenger-iOS-dummy.m │ ├── SwiftyMessenger-iOS-prefix.pch │ ├── SwiftyMessenger-iOS-umbrella.h │ ├── SwiftyMessenger-iOS.debug.xcconfig │ ├── SwiftyMessenger-iOS.modulemap │ ├── SwiftyMessenger-iOS.release.xcconfig │ └── SwiftyMessenger-iOS.xcconfig │ └── SwiftyMessenger-watchOS │ ├── Info.plist │ ├── SwiftyMessenger-watchOS-Info.plist │ ├── SwiftyMessenger-watchOS-dummy.m │ ├── SwiftyMessenger-watchOS-prefix.pch │ ├── SwiftyMessenger-watchOS-umbrella.h │ ├── SwiftyMessenger-watchOS.debug.xcconfig │ ├── SwiftyMessenger-watchOS.modulemap │ ├── SwiftyMessenger-watchOS.release.xcconfig │ └── SwiftyMessenger-watchOS.xcconfig ├── README.md ├── Resources └── SwiftyMessenger.gif ├── Sample iOS App ├── Sample Today Extension │ ├── Base.lproj │ │ └── MainInterface.storyboard │ ├── Info.plist │ ├── Sample Today Extension.entitlements │ └── TodayViewController.swift ├── Sample WatchOS App Extension │ ├── Assets.xcassets │ │ ├── Complication.complicationset │ │ │ ├── Circular.imageset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── Extra Large.imageset │ │ │ │ └── Contents.json │ │ │ ├── Modular.imageset │ │ │ │ └── Contents.json │ │ │ └── Utilitarian.imageset │ │ │ │ └── Contents.json │ │ └── Contents.json │ ├── ExtensionDelegate.swift │ ├── Info.plist │ ├── InterfaceController.swift │ └── Sample WatchOS App Extension.entitlements ├── Sample WatchOS App │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── Interface.storyboard │ └── Info.plist ├── Sample iOS App.xcodeproj │ └── project.pbxproj ├── Sample iOS App │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── Sample iOS App.entitlements │ └── ViewController.swift └── Sample iOS AppTests │ ├── Info.plist │ └── Sample_iOS_AppTests.swift ├── Source ├── Info-iOS.plist ├── Info-watchOS.plist ├── Messenger.swift ├── MessengerCoordinatedFileTransiting.swift ├── MessengerFileTransiting.swift ├── MessengerSession.swift ├── MessengerSessionContextTransiting.swift ├── MessengerSessionFileTransiting.swift ├── MessengerSessionMessageTransiting.swift ├── String+Path.swift └── SwiftyMessenger.h ├── SwiftyMessenger-iOSTests ├── Info.plist └── SwiftyMessenger_iOSTests.swift ├── SwiftyMessenger.podspec ├── SwiftyMessenger.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── SwiftyMessenger-iOS.xcscheme │ ├── SwiftyMessenger-iOSTests.xcscheme │ └── SwiftyMessenger-watchOS.xcscheme ├── SwiftyMessenger.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings └── scripts └── build-framework.sh /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: "SwiftyMessenger CI" 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | iOS: 11 | name: Test iOS 12 | runs-on: macOS-latest 13 | env: 14 | DEVELOPER_DIR: /Applications/Xcode_12.4.app/Contents/Developer 15 | strategy: 16 | matrix: 17 | destination: ["OS=14.4,name=iPhone 12 Pro"] #, "OS=12.4,name=iPhone XS", "OS=11.4,name=iPhone X", "OS=10.3.1,name=iPhone SE"] 18 | steps: 19 | - uses: actions/checkout@v1 20 | - name: iOS - ${{ matrix.destination }} 21 | run: set -o pipefail && xcodebuild -workspace "SwiftyMessenger.xcworkspace" -scheme "SwiftyMessenger-iOS" -destination "${{ matrix.destination }}" clean test | xcpretty 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /.slather.yml: -------------------------------------------------------------------------------- 1 | # .slather.yml 2 | 3 | coverage_service: cobertura_xml 4 | workspace: SwiftyMessenger.xcworkspace 5 | xcodeproj: SwiftyMessenger.xcodeproj 6 | scheme: SwiftyMessenger 7 | configuration: Debug 8 | source_directory: SwiftyMessenger 9 | output_directory: test/xml_report 10 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem 'xcpretty' 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | rouge (2.0.7) 5 | xcpretty (0.3.0) 6 | rouge (~> 2.0.7) 7 | 8 | PLATFORMS 9 | ruby 10 | 11 | DEPENDENCIES 12 | xcpretty 13 | 14 | BUNDLED WITH 15 | 2.1.4 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Abdullah Selek 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.0 2 | // 3 | // Package.swift 4 | // 5 | // Copyright (c) 2019 Abdullah Selek 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 | import PackageDescription 26 | 27 | let package = Package( 28 | name: "SwiftyMessenger", 29 | platforms: [ 30 | .iOS(.v10), 31 | .watchOS(.v3) 32 | ], 33 | products: [ 34 | .library( 35 | name: "SwiftyMessenger", 36 | targets: ["SwiftyMessenger"]) 37 | ], 38 | targets: [ 39 | .target( 40 | name: "SwiftyMessenger", 41 | path: "SwiftyMessenger") 42 | ], 43 | swiftLanguageVersions: [.v5] 44 | ) 45 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | def product_pods 2 | pod 'SwiftyMessenger', :path => '.' 3 | end 4 | 5 | workspace 'SwiftyMessenger.xcworkspace' 6 | project 'SwiftyMessenger.xcodeproj' 7 | 8 | target 'Sample iOS App' do 9 | platform :ios, '10.0' 10 | project 'Sample iOS App/Sample iOS App.xcodeproj' 11 | use_frameworks! 12 | inherit! :search_paths 13 | product_pods 14 | end 15 | 16 | target 'Sample WatchOS App Extension' do 17 | platform :watchos, '3.0' 18 | project 'Sample iOS App/Sample iOS App.xcodeproj' 19 | use_frameworks! 20 | inherit! :search_paths 21 | product_pods 22 | end 23 | 24 | target 'Sample Today Extension' do 25 | platform :ios, '10.0' 26 | project 'Sample iOS App/Sample iOS App.xcodeproj' 27 | use_frameworks! 28 | inherit! :search_paths 29 | product_pods 30 | end 31 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwiftyMessenger (0.3) 3 | 4 | DEPENDENCIES: 5 | - SwiftyMessenger (from `.`) 6 | 7 | EXTERNAL SOURCES: 8 | SwiftyMessenger: 9 | :path: "." 10 | 11 | SPEC CHECKSUMS: 12 | SwiftyMessenger: 2ee0529f83e34168a706da9dc18b534c7cbb2da9 13 | 14 | PODFILE CHECKSUM: fdf00c68fcef76b381788a265ddb2216b894e7ea 15 | 16 | COCOAPODS: 1.9.3 17 | -------------------------------------------------------------------------------- /Pods/Local Podspecs/SwiftyMessenger.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SwiftyMessenger", 3 | "version": "0.3", 4 | "summary": "Swift toolkit for passing messages between iOS apps and extensions.", 5 | "homepage": "https://github.com/abdullahselek/SwiftyMessenger", 6 | "license": { 7 | "type": "MIT", 8 | "file": "LICENSE" 9 | }, 10 | "authors": { 11 | "Abdullah Selek": "abdullahselek@gmail.com" 12 | }, 13 | "source": { 14 | "git": "https://github.com/abdullahselek/SwiftyMessenger.git", 15 | "tag": "0.3" 16 | }, 17 | "platforms": { 18 | "ios": "10.0", 19 | "watchos": "3.0" 20 | }, 21 | "source_files": "Source/*.swift", 22 | "requires_arc": true, 23 | "swift_versions": "5.0", 24 | "swift_version": "5.0" 25 | } 26 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SwiftyMessenger (0.3) 3 | 4 | DEPENDENCIES: 5 | - SwiftyMessenger (from `.`) 6 | 7 | EXTERNAL SOURCES: 8 | SwiftyMessenger: 9 | :path: "." 10 | 11 | SPEC CHECKSUMS: 12 | SwiftyMessenger: 2ee0529f83e34168a706da9dc18b534c7cbb2da9 13 | 14 | PODFILE CHECKSUM: fdf00c68fcef76b381788a265ddb2216b894e7ea 15 | 16 | COCOAPODS: 1.9.3 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Info.plist: -------------------------------------------------------------------------------- 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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension-Info.plist: -------------------------------------------------------------------------------- 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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwiftyMessenger 5 | 6 | MIT License 7 | 8 | Copyright (c) 2018 Abdullah Selek 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2018 Abdullah Selek 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | SwiftyMessenger 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Sample_Today_Extension : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Sample_Today_Extension 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_BUILD_DIR}/assetcatalog_generated_info.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Sample_Today_ExtensionVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Sample_Today_ExtensionVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyMessenger" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 10 | PODS_ROOT = ${SRCROOT}/../Pods 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Sample_Today_Extension { 2 | umbrella header "Pods-Sample Today Extension-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample Today Extension/Pods-Sample Today Extension.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework/Headers" 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 5 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyMessenger" 6 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 10 | PODS_ROOT = ${SRCROOT}/../Pods 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Info.plist: -------------------------------------------------------------------------------- 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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-Info.plist: -------------------------------------------------------------------------------- 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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwiftyMessenger 5 | 6 | MIT License 7 | 8 | Copyright (c) 2018 Abdullah Selek 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2018 Abdullah Selek 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | SwiftyMessenger 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Sample_WatchOS_App_Extension : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Sample_WatchOS_App_Extension 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyMessenger-watchOS/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyMessenger-watchOS/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | 23 | # Used as a return value for each invocation of `strip_invalid_archs` function. 24 | STRIP_BINARY_RETVAL=0 25 | 26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 29 | 30 | # Copies and strips a vendored framework 31 | install_framework() 32 | { 33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 34 | local source="${BUILT_PRODUCTS_DIR}/$1" 35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 37 | elif [ -r "$1" ]; then 38 | local source="$1" 39 | fi 40 | 41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 42 | 43 | if [ -L "${source}" ]; then 44 | echo "Symlinked..." 45 | source="$(readlink "${source}")" 46 | fi 47 | 48 | # Use filter instead of exclude so missing patterns don't throw errors. 49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 51 | 52 | local basename 53 | basename="$(basename -s .framework "$1")" 54 | binary="${destination}/${basename}.framework/${basename}" 55 | 56 | if ! [ -r "$binary" ]; then 57 | binary="${destination}/${basename}" 58 | elif [ -L "${binary}" ]; then 59 | echo "Destination binary is symlinked..." 60 | dirname="$(dirname "${binary}")" 61 | binary="${dirname}/$(readlink "${binary}")" 62 | fi 63 | 64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 66 | strip_invalid_archs "$binary" 67 | fi 68 | 69 | # Resign the code if required by the build settings to avoid unstable apps 70 | code_sign_if_enabled "${destination}/$(basename "$1")" 71 | 72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 74 | local swift_runtime_libs 75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 76 | for lib in $swift_runtime_libs; do 77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 79 | code_sign_if_enabled "${destination}/${lib}" 80 | done 81 | fi 82 | } 83 | 84 | # Copies and strips a vendored dSYM 85 | install_dsym() { 86 | local source="$1" 87 | warn_missing_arch=${2:-true} 88 | if [ -r "$source" ]; then 89 | # Copy the dSYM into the targets temp dir. 90 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 91 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 92 | 93 | local basename 94 | basename="$(basename -s .dSYM "$source")" 95 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 96 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 97 | 98 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 99 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 100 | strip_invalid_archs "$binary" "$warn_missing_arch" 101 | fi 102 | 103 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 104 | # Move the stripped file into its final destination. 105 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 106 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 107 | else 108 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 109 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 110 | fi 111 | fi 112 | } 113 | 114 | # Copies the bcsymbolmap files of a vendored framework 115 | install_bcsymbolmap() { 116 | local bcsymbolmap_path="$1" 117 | local destination="${BUILT_PRODUCTS_DIR}" 118 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 119 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 120 | } 121 | 122 | # Signs a framework with the provided identity 123 | code_sign_if_enabled() { 124 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 125 | # Use the current code_sign_identity 126 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 127 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 128 | 129 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 130 | code_sign_cmd="$code_sign_cmd &" 131 | fi 132 | echo "$code_sign_cmd" 133 | eval "$code_sign_cmd" 134 | fi 135 | } 136 | 137 | # Strip invalid architectures 138 | strip_invalid_archs() { 139 | binary="$1" 140 | warn_missing_arch=${2:-true} 141 | # Get architectures for current target binary 142 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 143 | # Intersect them with the architectures we are building for 144 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 145 | # If there are no archs supported by this binary then warn the user 146 | if [[ -z "$intersected_archs" ]]; then 147 | if [[ "$warn_missing_arch" == "true" ]]; then 148 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 149 | fi 150 | STRIP_BINARY_RETVAL=0 151 | return 152 | fi 153 | stripped="" 154 | for arch in $binary_archs; do 155 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 156 | # Strip non-valid architectures in-place 157 | lipo -remove "$arch" -output "$binary" "$binary" 158 | stripped="$stripped $arch" 159 | fi 160 | done 161 | if [[ "$stripped" ]]; then 162 | echo "Stripped $binary of architectures:$stripped" 163 | fi 164 | STRIP_BINARY_RETVAL=1 165 | } 166 | 167 | install_artifact() { 168 | artifact="$1" 169 | base="$(basename "$artifact")" 170 | case $base in 171 | *.framework) 172 | install_framework "$artifact" 173 | ;; 174 | *.dSYM) 175 | # Suppress arch warnings since XCFrameworks will include many dSYM files 176 | install_dsym "$artifact" "false" 177 | ;; 178 | *.bcsymbolmap) 179 | install_bcsymbolmap "$artifact" 180 | ;; 181 | *) 182 | echo "error: Unrecognized artifact "$artifact"" 183 | ;; 184 | esac 185 | } 186 | 187 | copy_artifacts() { 188 | file_list="$1" 189 | while read artifact; do 190 | install_artifact "$artifact" 191 | done <$file_list 192 | } 193 | 194 | ARTIFACT_LIST_FILE="${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt" 195 | if [ -r "${ARTIFACT_LIST_FILE}" ]; then 196 | copy_artifacts "${ARTIFACT_LIST_FILE}" 197 | fi 198 | 199 | if [[ "$CONFIGURATION" == "Debug" ]]; then 200 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftyMessenger-watchOS/SwiftyMessenger.framework" 201 | fi 202 | if [[ "$CONFIGURATION" == "Release" ]]; then 203 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftyMessenger-watchOS/SwiftyMessenger.framework" 204 | fi 205 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 206 | wait 207 | fi 208 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_BUILD_DIR}/assetcatalog_generated_info.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Sample_WatchOS_App_ExtensionVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Sample_WatchOS_App_ExtensionVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-watchOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-watchOS/SwiftyMessenger.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyMessenger" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 11 | PODS_ROOT = ${SRCROOT}/../Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Sample_WatchOS_App_Extension { 2 | umbrella header "Pods-Sample WatchOS App Extension-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample WatchOS App Extension/Pods-Sample WatchOS App Extension.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-watchOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-watchOS/SwiftyMessenger.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyMessenger" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 11 | PODS_ROOT = ${SRCROOT}/../Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Info.plist: -------------------------------------------------------------------------------- 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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-Info.plist: -------------------------------------------------------------------------------- 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 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SwiftyMessenger 5 | 6 | MIT License 7 | 8 | Copyright (c) 2018 Abdullah Selek 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2018 Abdullah Selek 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | SwiftyMessenger 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Sample_iOS_App : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Sample_iOS_App 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyMessenger.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | 23 | # Used as a return value for each invocation of `strip_invalid_archs` function. 24 | STRIP_BINARY_RETVAL=0 25 | 26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 29 | 30 | # Copies and strips a vendored framework 31 | install_framework() 32 | { 33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 34 | local source="${BUILT_PRODUCTS_DIR}/$1" 35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 37 | elif [ -r "$1" ]; then 38 | local source="$1" 39 | fi 40 | 41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 42 | 43 | if [ -L "${source}" ]; then 44 | echo "Symlinked..." 45 | source="$(readlink "${source}")" 46 | fi 47 | 48 | # Use filter instead of exclude so missing patterns don't throw errors. 49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 51 | 52 | local basename 53 | basename="$(basename -s .framework "$1")" 54 | binary="${destination}/${basename}.framework/${basename}" 55 | 56 | if ! [ -r "$binary" ]; then 57 | binary="${destination}/${basename}" 58 | elif [ -L "${binary}" ]; then 59 | echo "Destination binary is symlinked..." 60 | dirname="$(dirname "${binary}")" 61 | binary="${dirname}/$(readlink "${binary}")" 62 | fi 63 | 64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 66 | strip_invalid_archs "$binary" 67 | fi 68 | 69 | # Resign the code if required by the build settings to avoid unstable apps 70 | code_sign_if_enabled "${destination}/$(basename "$1")" 71 | 72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 74 | local swift_runtime_libs 75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 76 | for lib in $swift_runtime_libs; do 77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 79 | code_sign_if_enabled "${destination}/${lib}" 80 | done 81 | fi 82 | } 83 | 84 | # Copies and strips a vendored dSYM 85 | install_dsym() { 86 | local source="$1" 87 | warn_missing_arch=${2:-true} 88 | if [ -r "$source" ]; then 89 | # Copy the dSYM into the targets temp dir. 90 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 91 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 92 | 93 | local basename 94 | basename="$(basename -s .dSYM "$source")" 95 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 96 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 97 | 98 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 99 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 100 | strip_invalid_archs "$binary" "$warn_missing_arch" 101 | fi 102 | 103 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 104 | # Move the stripped file into its final destination. 105 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 106 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 107 | else 108 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 109 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 110 | fi 111 | fi 112 | } 113 | 114 | # Copies the bcsymbolmap files of a vendored framework 115 | install_bcsymbolmap() { 116 | local bcsymbolmap_path="$1" 117 | local destination="${BUILT_PRODUCTS_DIR}" 118 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 119 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 120 | } 121 | 122 | # Signs a framework with the provided identity 123 | code_sign_if_enabled() { 124 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 125 | # Use the current code_sign_identity 126 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 127 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 128 | 129 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 130 | code_sign_cmd="$code_sign_cmd &" 131 | fi 132 | echo "$code_sign_cmd" 133 | eval "$code_sign_cmd" 134 | fi 135 | } 136 | 137 | # Strip invalid architectures 138 | strip_invalid_archs() { 139 | binary="$1" 140 | warn_missing_arch=${2:-true} 141 | # Get architectures for current target binary 142 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 143 | # Intersect them with the architectures we are building for 144 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 145 | # If there are no archs supported by this binary then warn the user 146 | if [[ -z "$intersected_archs" ]]; then 147 | if [[ "$warn_missing_arch" == "true" ]]; then 148 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 149 | fi 150 | STRIP_BINARY_RETVAL=0 151 | return 152 | fi 153 | stripped="" 154 | for arch in $binary_archs; do 155 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 156 | # Strip non-valid architectures in-place 157 | lipo -remove "$arch" -output "$binary" "$binary" 158 | stripped="$stripped $arch" 159 | fi 160 | done 161 | if [[ "$stripped" ]]; then 162 | echo "Stripped $binary of architectures:$stripped" 163 | fi 164 | STRIP_BINARY_RETVAL=1 165 | } 166 | 167 | install_artifact() { 168 | artifact="$1" 169 | base="$(basename "$artifact")" 170 | case $base in 171 | *.framework) 172 | install_framework "$artifact" 173 | ;; 174 | *.dSYM) 175 | # Suppress arch warnings since XCFrameworks will include many dSYM files 176 | install_dsym "$artifact" "false" 177 | ;; 178 | *.bcsymbolmap) 179 | install_bcsymbolmap "$artifact" 180 | ;; 181 | *) 182 | echo "error: Unrecognized artifact "$artifact"" 183 | ;; 184 | esac 185 | } 186 | 187 | copy_artifacts() { 188 | file_list="$1" 189 | while read artifact; do 190 | install_artifact "$artifact" 191 | done <$file_list 192 | } 193 | 194 | ARTIFACT_LIST_FILE="${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt" 195 | if [ -r "${ARTIFACT_LIST_FILE}" ]; then 196 | copy_artifacts "${ARTIFACT_LIST_FILE}" 197 | fi 198 | 199 | if [[ "$CONFIGURATION" == "Debug" ]]; then 200 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework" 201 | fi 202 | if [[ "$CONFIGURATION" == "Release" ]]; then 203 | install_framework "${BUILT_PRODUCTS_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework" 204 | fi 205 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 206 | wait 207 | fi 208 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_BUILD_DIR}/assetcatalog_generated_info.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Sample_iOS_AppVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Sample_iOS_AppVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyMessenger" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 11 | PODS_ROOT = ${SRCROOT}/../Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Sample_iOS_App { 2 | umbrella header "Pods-Sample iOS App-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sample iOS App/Pods-Sample iOS App.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS/SwiftyMessenger.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SwiftyMessenger" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.. 11 | PODS_ROOT = ${SRCROOT}/../Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/Info.plist: -------------------------------------------------------------------------------- 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 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS-Info.plist: -------------------------------------------------------------------------------- 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 | 0.3.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SwiftyMessenger_iOS : NSObject 3 | @end 4 | @implementation PodsDummy_SwiftyMessenger_iOS 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double SwiftyMessengerVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char SwiftyMessengerVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS.debug.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS.modulemap: -------------------------------------------------------------------------------- 1 | framework module SwiftyMessenger { 2 | umbrella header "SwiftyMessenger-iOS-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS.release.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-iOS/SwiftyMessenger-iOS.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-iOS 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/Info.plist: -------------------------------------------------------------------------------- 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 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS-Info.plist: -------------------------------------------------------------------------------- 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 | 0.3.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SwiftyMessenger_watchOS : NSObject 3 | @end 4 | @implementation PodsDummy_SwiftyMessenger_watchOS 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double SwiftyMessengerVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char SwiftyMessengerVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS.debug.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-watchOS 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS.modulemap: -------------------------------------------------------------------------------- 1 | framework module SwiftyMessenger { 2 | umbrella header "SwiftyMessenger-watchOS-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS.release.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-watchOS 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SwiftyMessenger-watchOS/SwiftyMessenger-watchOS.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SwiftyMessenger-watchOS 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![SwiftyMessenger CI](https://github.com/abdullahselek/SwiftyMessenger/workflows/SwiftyMessenger%20CI/badge.svg)](https://github.com/abdullahselek/SwiftyMessenger/actions) 2 | [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/SwiftyMessenger.svg)](http://cocoapods.org/pods/SwiftyMessenger) 3 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 4 | ![Platform](https://img.shields.io/cocoapods/p/SwiftyMessenger.svg?style=flat) 5 | ![License](https://img.shields.io/dub/l/vibe-d.svg) 6 | 7 | ``` 8 | _________ ___ ___ _ _____ _________ ___ ___ 9 | / / \ \ / / |_| ( ___ \ \__ __/ \ \ / / 10 | / _____/ \ \ /\ / / | | | ( \/ ) ( \ \/ / 11 | \_____ \ \ \/ \/ / | | | (_ | | \ / 12 | / \ \ ____ / | | | _) | | ) ( 13 | /_______ / \/ \/ |_| | ( | | | | 14 | \/ | ) )_( |__| 15 | |/ 16 | _____ ______ ________ ________ ______ __ __ _____ ______ _________ 17 | / \ ( ____\ / / / / ( ____\ | \ | | / \ ( ____\ \______ \ 18 | / \ | ( / ____/ / ____/ | ( | |\ | | / ____\ | ( | \ 19 | / /\ /\ \ | (__ \_____ \ \_____ \ | (__ | | \ | | / /__/ | | (__ | |____\ 20 | / / Y \ \ | __) / \ / \ | __) | | \ | | \______ / | __) | \\ 21 | / / \ \ | ( /_______/ /_______/ | ( | | \| | _____/ / | ( | | \\ 22 | |_/ |__| | (___/\ \/ \/ | (___/\ |__| |__| |_______/ | (___/\ |____| |_| 23 | (______/ (______/ (______/ 24 | ``` 25 | 26 | # SwiftyMessenger 27 | 28 | Swift toolkit for passing messages between iOS apps and extensions. It creates a bridge between container app and iOS extensions. SwiftyMessenger archives messages in files which are written to the application's shared App Group. SwiftyMessenger resembles interprocess communication between the app and the extension without a interprocess communication. 29 | 30 | It also supports CFNotificationCenter Darwin Notifications in an effort to support realtime change notifications. When a message passed, interested parties can listen and can be notified (almost instant) of these changes on both side. 31 | 32 |

33 | Sample App 34 |

35 | 36 | ## Requirements 37 | 38 | | SwiftyMessenger Version | Minimum iOS Target | Minimum watchOS Target | Swift Version | 39 | |:--------------------:|:---------------------------:|:---------------------------:|:--------------------:| 40 | | 0.4.0 | iOS 10 | watchOS 3.0 | Swift 5.x | 41 | | 0.2 | iOS 9 | watchOS 2.0 | Swift 4.2 | 42 | | 0.1 | iOS 9 | watchOS 2.0 | Swift 4.1 | 43 | 44 | ### NOTE 45 | 46 | SwiftyMessenger can only work with App Group identifiers and Entitlements. 47 | 48 | ## CocoaPods 49 | 50 | CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command: 51 | ``` 52 | $ gem install cocoapods 53 | ``` 54 | 55 | To integrate SwiftyMessenger into your Xcode project using CocoaPods, specify it in your Podfile: 56 | ``` 57 | source 'https://github.com/CocoaPods/Specs.git' 58 | platform :ios, '10.0' 59 | use_frameworks! 60 | 61 | target '' do 62 | pod 'SwiftyMessenger', '~>0.4.0' 63 | end 64 | ``` 65 | 66 | ## Carthage 67 | 68 | Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. 69 | 70 | You can install Carthage with Homebrew using the following command: 71 | 72 | ``` 73 | brew update 74 | brew install carthage 75 | ``` 76 | 77 | To integrate SwiftyMessenger into your Xcode project using Carthage, specify it in your Cartfile: 78 | 79 | ``` 80 | github "abdullahselek/SwiftyMessenger" ~> 0.4.0 81 | ``` 82 | 83 | ## Swift Package Manager 84 | 85 | Modify your Package.swift file to include the following dependency: 86 | 87 | ``` 88 | .package(url: "https://github.com/abdullahselek/SwiftyMessenger.git", from: "0.4.0") 89 | ``` 90 | 91 | ## XCFramework 92 | 93 | XCFrameworks require Xcode 11 or later and integration is very similar to integration of .framework format. Please use script [scripts/build-framework.sh](scripts/build-framework.sh) to generate binary SwiftyMessenger.xcframework archive that you can use as a dependency in Xcode. 94 | 95 | SwiftyMessenger.xcframework is a Release (Optimized) binary that offer best available Swift code performance. 96 | 97 | ## Usage 98 | 99 | **Initialization** 100 | 101 | ``` 102 | messenger = Messenger(withApplicationGroupIdentifier: "group.com.abdullahselek.swiftymessenger", directory: "messenger") 103 | ``` 104 | 105 | **Passing message** 106 | 107 | ``` 108 | messenger.passMessage(message: ["selectedCell": title], identifier: "selection") 109 | ``` 110 | 111 | **Reading message** 112 | 113 | ``` 114 | if let message = messenger.messageForIdentifier(identifier: "button") as? [String: Any] { 115 | let buttonTitle = message["buttonTitle"] as? String 116 | } 117 | ``` 118 | 119 | **Listen message changes with identifier** 120 | 121 | ``` 122 | messenger.listenForMessage(withIdentifier: "button") { message in 123 | guard let message = message as? [String: Any] else { 124 | return 125 | } 126 | let buttonTitle = message["buttonTitle"] as? String 127 | } 128 | ``` 129 | 130 | ## Support for WatchConnectivity 131 | 132 | SwiftyMessenger suports **WatchConnectivity** provided by Apple on **watchOS** extensions. 133 | 134 | Here are two little notes you need to know if you want to use WatchConnectivity support in your app: 135 | 136 | - `MessengerSession` is a singleton subclass that supports listening for WatchConnectivity messages. It can be used to listen `Messenger` messages you expect to receive from the WatchConnectivity framework. Be sure to activate the session once your listeners are set so that you can begin receiving message notifications. 137 | 138 | - You can use `MessengerSessionContextTransiting` when creating your messenger, but it can easily overload the pipeline by sending too many messages at once. 139 | 140 | ## Transiting Types 141 | 142 | You can find 5 available types under **TransitingType**. 143 | 144 | - `file` (Message transiting by archiving and unarchiving messages that are written and read to files) 145 | - `coordinatedFile` (Uses FileCoordinator) 146 | - `sessionContext` (Support for the WatchConnectivity framework's Application Context) 147 | - `sessionMessage` (Support for the WatchConnectivity framework's real time message passing ability) 148 | - `sessionFile` (Support for the WatchConnectivity framework's file transfer ability) 149 | 150 | ## License 151 | 152 | SwiftyMessenger is released under the MIT license. See LICENSE for details. 153 | 154 | ## Credits 155 | 156 | Inspired by MutualMobile. Improved and all coded in new programming language Swift. 157 | -------------------------------------------------------------------------------- /Resources/SwiftyMessenger.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullahselek/SwiftyMessenger/6ef022a6520ba8d3f49444c2391105e4a695df53/Resources/SwiftyMessenger.gif -------------------------------------------------------------------------------- /Sample iOS App/Sample Today Extension/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Sample iOS App/Sample Today Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Sample Today Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionMainStoryboard 26 | MainInterface 27 | NSExtensionPointIdentifier 28 | com.apple.widget-extension 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Sample iOS App/Sample Today Extension/Sample Today Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.abdullahselek.swiftymessenger 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample iOS App/Sample Today Extension/TodayViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodayViewController.swift 3 | // Sample Today Extension 4 | // 5 | // Created by Abdullah Selek on 16.07.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import NotificationCenter 11 | import SwiftyMessenger 12 | 13 | class TodayViewController: UIViewController, NCWidgetProviding { 14 | 15 | private static let groupIdentifier = "group.com.abdullahselek.swiftymessenger" 16 | private static let directory = "messenger" 17 | private var messenger: Messenger! 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | messenger = Messenger(withApplicationGroupIdentifier: TodayViewController.groupIdentifier, 22 | directory: TodayViewController.directory) 23 | } 24 | 25 | @IBAction func oneTapped(_ sender: Any) { 26 | messenger.passMessage(message: ["buttonTitle": "Today-One"], identifier: "button") 27 | } 28 | 29 | @IBAction func twoTapped(_ sender: Any) { 30 | messenger.passMessage(message: ["buttonTitle": "Today-Two"], identifier: "button") 31 | } 32 | 33 | func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { 34 | completionHandler(NCUpdateResult.newData) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">145" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Assets.xcassets/Complication.complicationset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "idiom" : "watch", 5 | "filename" : "Circular.imageset", 6 | "role" : "circular" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "filename" : "Extra Large.imageset", 11 | "role" : "extra-large" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "filename" : "Modular.imageset", 16 | "role" : "modular" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "filename" : "Utilitarian.imageset", 21 | "role" : "utilitarian" 22 | } 23 | ], 24 | "info" : { 25 | "version" : 1, 26 | "author" : "xcode" 27 | } 28 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">145" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">145" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">145" 12 | } 13 | ], 14 | "info" : { 15 | "version" : 1, 16 | "author" : "xcode" 17 | } 18 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/ExtensionDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExtensionDelegate.swift 3 | // Sample WatchOS App Extension 4 | // 5 | // Created by Abdullah Selek on 03.06.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | 11 | class ExtensionDelegate: NSObject, WKExtensionDelegate { 12 | 13 | func applicationDidFinishLaunching() { 14 | // Perform any final initialization of your application. 15 | } 16 | 17 | func applicationDidBecomeActive() { 18 | // 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. 19 | } 20 | 21 | func applicationWillResignActive() { 22 | // 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. 23 | // Use this method to pause ongoing tasks, disable timers, etc. 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Sample WatchOS App Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | WKAppBundleIdentifier 28 | com.abdullahselek.Sample-iOS-App.watchkitapp 29 | 30 | NSExtensionPointIdentifier 31 | com.apple.watchkit 32 | 33 | WKExtensionDelegateClassName 34 | $(PRODUCT_MODULE_NAME).ExtensionDelegate 35 | 36 | 37 | -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/InterfaceController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.swift 3 | // Sample WatchOS App Extension 4 | // 5 | // Created by Abdullah Selek on 03.06.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | import Foundation 11 | import SwiftyMessenger 12 | 13 | class InterfaceController: WKInterfaceController { 14 | 15 | private static let groupIdentifier = "group.com.abdullahselek.swiftymessenger" 16 | private static let directory = "messenger" 17 | 18 | private var messengerSession: MessengerSession! 19 | private var messenger: Messenger! 20 | 21 | @IBOutlet weak var selectedCellLabel: WKInterfaceLabel! 22 | 23 | override func awake(withContext context: Any?) { 24 | super.awake(withContext: context) 25 | 26 | messengerSession = MessengerSession.shared 27 | messenger = Messenger(withApplicationGroupIdentifier: InterfaceController.groupIdentifier, 28 | directory: InterfaceController.directory, 29 | transitingType: .sessionContext) 30 | 31 | if let message = messenger.messageForIdentifier(identifier: "selection") as? [String: Any] { 32 | let string = message["selectedCell"] as? String 33 | selectedCellLabel.setText(string) 34 | } 35 | 36 | messengerSession.listenForMessage(withIdentifier: "selection") { message in 37 | guard let message = message as? [String: Any] else { 38 | return 39 | } 40 | let string = message["selectedCell"] as? String 41 | self.selectedCellLabel.setText(string) 42 | } 43 | messengerSession.activateSession() 44 | } 45 | 46 | @IBAction func didObjCTap(sender: WKInterfaceButton) { 47 | messenger.passMessage(message: ["buttonTitle": "Objective-C"], identifier: "button") 48 | } 49 | 50 | @IBAction func didSwiftTap(sender: WKInterfaceButton) { 51 | messenger.passMessage(message: ["buttonTitle": "Swift"], identifier: "button") 52 | } 53 | 54 | @IBAction func didXcodeTap(sender: WKInterfaceButton) { 55 | messenger.passMessage(message: ["buttonTitle": "Xcode"], identifier: "button") 56 | } 57 | 58 | override func willActivate() { 59 | // This method is called when watch view controller is about to be visible to user 60 | super.willActivate() 61 | } 62 | 63 | override func didDeactivate() { 64 | // This method is called when watch view controller is no longer visible 65 | super.didDeactivate() 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App Extension/Sample WatchOS App Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.abdullahselek.swiftymessenger 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "44x44", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "appLauncher", 41 | "subtype" : "40mm" 42 | }, 43 | { 44 | "size" : "50x50", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "appLauncher", 48 | "subtype" : "44mm" 49 | }, 50 | { 51 | "size" : "86x86", 52 | "idiom" : "watch", 53 | "scale" : "2x", 54 | "role" : "quickLook", 55 | "subtype" : "38mm" 56 | }, 57 | { 58 | "size" : "98x98", 59 | "idiom" : "watch", 60 | "scale" : "2x", 61 | "role" : "quickLook", 62 | "subtype" : "42mm" 63 | }, 64 | { 65 | "size" : "108x108", 66 | "idiom" : "watch", 67 | "scale" : "2x", 68 | "role" : "quickLook", 69 | "subtype" : "44mm" 70 | }, 71 | { 72 | "idiom" : "watch-marketing", 73 | "size" : "1024x1024", 74 | "scale" : "1x" 75 | }, 76 | { 77 | "size" : "44x44", 78 | "idiom" : "watch", 79 | "scale" : "2x", 80 | "role" : "longLook", 81 | "subtype" : "42mm" 82 | } 83 | ], 84 | "info" : { 85 | "version" : 1, 86 | "author" : "xcode" 87 | } 88 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Sample iOS App/Sample WatchOS App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Sample iOS App 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | UISupportedInterfaceOrientations 24 | 25 | UIInterfaceOrientationPortrait 26 | UIInterfaceOrientationPortraitUpsideDown 27 | 28 | WKCompanionAppBundleIdentifier 29 | com.abdullahselek.Sample-iOS-App 30 | WKWatchKitApp 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Sample iOS App 4 | // 5 | // Created by Abdullah Selek on 03.06.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/Sample iOS App.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.abdullahselek.swiftymessenger 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS App/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Sample iOS App 4 | // 5 | // Created by Abdullah Selek on 03.06.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SwiftyMessenger 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet weak var tableView: UITableView! 15 | @IBOutlet weak var selectedButtonLabel: UILabel! 16 | 17 | private static let groupIdentifier = "group.com.abdullahselek.swiftymessenger" 18 | private static let directory = "messenger" 19 | 20 | private var messenger: Messenger! 21 | private var watchConnectivityMessenger: Messenger! 22 | private var messengerListeningSession: MessengerSession! 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | 27 | tableView.reloadData() 28 | 29 | messenger = Messenger(withApplicationGroupIdentifier: ViewController.groupIdentifier, directory: ViewController.directory) 30 | messengerListeningSession = MessengerSession.shared 31 | watchConnectivityMessenger = Messenger(withApplicationGroupIdentifier: ViewController.groupIdentifier, 32 | directory: ViewController.directory, 33 | transitingType: .sessionContext) 34 | 35 | messenger.listenForMessage(withIdentifier: "button") { message in 36 | guard let message = message as? [String: Any] else { 37 | return 38 | } 39 | let buttonTitle = message["buttonTitle"] as? String 40 | self.selectedButtonLabel.text = buttonTitle 41 | } 42 | 43 | messengerListeningSession.listenForMessage(withIdentifier: "button") { message in 44 | guard let message = message as? [String: Any] else { 45 | return 46 | } 47 | let buttonTitle = message["buttonTitle"] as? String 48 | self.selectedButtonLabel.text = buttonTitle 49 | } 50 | messengerListeningSession.activateSession() 51 | } 52 | 53 | override func viewDidAppear(_ animated: Bool) { 54 | super.viewDidAppear(animated) 55 | 56 | if let message = messenger.messageForIdentifier(identifier: "button") as? [String: Any] { 57 | let buttonTitle = message["buttonTitle"] as? String 58 | self.selectedButtonLabel.text = buttonTitle 59 | } 60 | 61 | if let message = watchConnectivityMessenger.messageForIdentifier(identifier: "button") as? [String: Any] { 62 | let buttonTitle = message["buttonTitle"] as? String 63 | self.selectedButtonLabel.text = buttonTitle 64 | } 65 | } 66 | 67 | } 68 | 69 | extension ViewController: UITableViewDataSource { 70 | 71 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 72 | return 3 73 | } 74 | 75 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 76 | let tableViewCell = tableView.dequeueReusableCell(withIdentifier: "TableViewCellIdentifier") as! TextTableViewCell 77 | tableViewCell.titleLabel?.text = String(format: "%d", indexPath.row) 78 | return tableViewCell 79 | } 80 | 81 | } 82 | 83 | extension ViewController: UITableViewDelegate { 84 | 85 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 86 | let tableViewCell = tableView.cellForRow(at: indexPath) as? TextTableViewCell 87 | let title = tableViewCell?.titleLabel.text 88 | 89 | // Pass a message for the selection identifier. 90 | messenger.passMessage(message: ["selectedCell": title], identifier: "selection") 91 | watchConnectivityMessenger.passMessage(message: ["selectedCell": title], identifier: "selection") 92 | } 93 | 94 | } 95 | 96 | class TextTableViewCell: UITableViewCell { 97 | 98 | @IBOutlet weak var titleLabel: UILabel! 99 | 100 | } 101 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS AppTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Sample iOS App/Sample iOS AppTests/Sample_iOS_AppTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sample_iOS_AppTests.swift 3 | // Sample iOS AppTests 4 | // 5 | // Created by Abdullah Selek on 03.06.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Sample_iOS_App 11 | 12 | class Sample_iOS_AppTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Source/Info-iOS.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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Source/Info-watchOS.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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Source/Messenger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Messenger.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | import CoreFoundation 26 | 27 | public enum TransitingType { 28 | case file 29 | case coordinatedFile 30 | case sessionContext 31 | case sessionMessage 32 | case sessionFile 33 | } 34 | 35 | /** 36 | Creates a connection between a containing iOS application and an extension. Used to pass data or 37 | commands back and forth between the two locations. 38 | */ 39 | open class Messenger: TransitingDelegate { 40 | 41 | open var transitingDelegate: FileTransiting? 42 | private var listenerBlocks = [String: (Any) -> Void]() 43 | private static let NotificationName = NSNotification.Name(rawValue: "MessengerNotificationName") 44 | 45 | public init(withApplicationGroupIdentifier identifier: String?, directory: String?) { 46 | transitingDelegate = MessengerFileTransiting(withApplicationGroupIdentifier: identifier, directory: directory) 47 | NotificationCenter.default.addObserver(self, 48 | selector: #selector(Messenger.didReceiveMessageNotification(notification:)), 49 | name: Messenger.NotificationName, 50 | object: self) 51 | } 52 | 53 | public convenience init(withApplicationGroupIdentifier identifier: String, 54 | directory: String?, 55 | transitingType: TransitingType) { 56 | self.init(withApplicationGroupIdentifier: identifier, directory: directory) 57 | switch transitingType { 58 | case .file: 59 | break 60 | case .coordinatedFile: 61 | transitingDelegate = MessengerCoordinatedFileTransiting(withApplicationGroupIdentifier: identifier, directory: directory) 62 | case .sessionContext: 63 | transitingDelegate = MessengerSessionContextTransiting(withApplicationGroupIdentifier: identifier, directory: directory) 64 | case .sessionFile: 65 | transitingDelegate = MessengerSessionFileTransiting(withApplicationGroupIdentifier: identifier, directory: directory) 66 | case .sessionMessage: 67 | transitingDelegate = MessengerSessionMessageTransiting(withApplicationGroupIdentifier: identifier, directory: directory) 68 | } 69 | } 70 | 71 | private func notificationCallBack(observer: UnsafeMutableRawPointer, identifier: String) { 72 | NotificationCenter.default.post(name: Messenger.NotificationName, object:observer, userInfo: ["identifier": identifier]) 73 | } 74 | 75 | private func registerForNotification(withIdentifier identifier: String) { 76 | unregisterForNotification(withIdentifier: identifier) 77 | let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter() 78 | let str = identifier as CFString 79 | let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque()) 80 | CFNotificationCenterAddObserver(notificationCenter, observer, { 81 | (notificationCenter, observer, notificationName, rawPointer, dictionary) -> Void in 82 | if let observer = observer, let notificationName = notificationName { 83 | let mySelf = Unmanaged.fromOpaque(observer).takeUnretainedValue() 84 | mySelf.notificationCallBack(observer: observer, identifier: notificationName.rawValue as String) 85 | } 86 | }, str, nil, .deliverImmediately) 87 | } 88 | 89 | private func unregisterForNotification(withIdentifier identifier: String) { 90 | let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter() 91 | let str = identifier as CFString 92 | let observer = UnsafeRawPointer(Unmanaged.passUnretained(self).toOpaque()) 93 | CFNotificationCenterRemoveObserver(notificationCenter, observer, CFNotificationName(str), nil) 94 | } 95 | 96 | @objc private func didReceiveMessageNotification(notification: Notification) { 97 | guard let userInfo = notification.userInfo else { 98 | return 99 | } 100 | guard let identifier = userInfo["identifier"] as? String else { 101 | return 102 | } 103 | let message = transitingDelegate?.messageForIdentifier(identifier: identifier) 104 | notifyListenerForMessage(withIdentifier: identifier, message: message) 105 | } 106 | 107 | open func notifyListenerForMessage(withIdentifier identifier: String?, message: Any?) { 108 | guard let identifier = identifier, let message = message else { 109 | return 110 | } 111 | guard let listenerBlock = listenerBlock(forIdentifier: identifier) else { 112 | return 113 | } 114 | DispatchQueue.main.async { 115 | listenerBlock(message) 116 | } 117 | } 118 | 119 | private func listenerBlock(forIdentifier identifier: String) -> ((Any) -> Void)? { 120 | return listenerBlocks[identifier] 121 | } 122 | 123 | private func sendNotification(forMessageIdentifier identifier: String) { 124 | let notificationCenter = CFNotificationCenterGetDarwinNotifyCenter() 125 | let deliverImmediately = true 126 | let str = identifier as CFString 127 | CFNotificationCenterPostNotification(notificationCenter, CFNotificationName(str), nil, nil, deliverImmediately) 128 | } 129 | 130 | /** 131 | Passes a message associated with a given identifier. This is the primary means 132 | of passing information through the messenger. 133 | */ 134 | open func passMessage(message: Any?, identifier: String?) { 135 | guard let identifier = identifier else { 136 | return 137 | } 138 | if transitingDelegate?.writeMessage(message: message, identifier: identifier) == true { 139 | sendNotification(forMessageIdentifier: identifier) 140 | } 141 | } 142 | 143 | /** 144 | Returns the value of a message with a specific identifier as an object. 145 | */ 146 | open func messageForIdentifier(identifier: String?) -> Any? { 147 | return transitingDelegate?.messageForIdentifier(identifier: identifier) 148 | } 149 | 150 | /** 151 | Clears the contents of a specific message with a given identifier. 152 | */ 153 | open func clearMessageContents(identifer: String?) { 154 | transitingDelegate?.deleteContent(withIdentifier: identifer) 155 | } 156 | 157 | /** 158 | Clears the contents of your optional message directory to give you a clean state. 159 | */ 160 | open func clearAllMessageContents() { 161 | transitingDelegate?.deleteContentForAllMessages() 162 | } 163 | 164 | /** 165 | Begins listening for notifications of changes to a message with a specific identifier. 166 | If notifications are observed then the given listener block will be called along with the actual 167 | message. 168 | */ 169 | open func listenForMessage(withIdentifier identifier: String?, listener: @escaping ((Any) -> Void)) { 170 | guard let identifier = identifier else { 171 | return 172 | } 173 | listenerBlocks[identifier] = listener 174 | registerForNotification(withIdentifier: identifier) 175 | } 176 | 177 | /** 178 | Stops listening for change notifications for a given message identifier. 179 | */ 180 | open func stopListeningForMessage(withIdentifier identifier: String?) { 181 | guard let identifier = identifier else { 182 | return 183 | } 184 | listenerBlocks[identifier] = nil 185 | unregisterForNotification(withIdentifier: identifier) 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /Source/MessengerCoordinatedFileTransiting.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerCoordinatedFileTransiting.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | Inherits from the default implementation of the FileTransiting protocol 27 | and implements message transiting in a similar way but using FileCoordinator for its file 28 | reading and writing. 29 | */ 30 | open class MessengerCoordinatedFileTransiting: MessengerFileTransiting { 31 | 32 | open var additionalFileWritingOptions: NSData.WritingOptions! 33 | 34 | override open func writeMessage(message: Any?, identifier: String) -> Bool { 35 | if identifier.isEmpty { 36 | return false 37 | } 38 | guard let message = message else { 39 | return false 40 | } 41 | let data = NSKeyedArchiver.archivedData(withRootObject: message) as NSData 42 | guard let filePath = self.filePath(forIdentifier: identifier) else { 43 | return false 44 | } 45 | let fileURL = URL(fileURLWithPath: filePath) 46 | let fileCoordinator = NSFileCoordinator(filePresenter: nil) 47 | var error: NSError? 48 | var success = false 49 | fileCoordinator.coordinate(readingItemAt: fileURL, 50 | options: NSFileCoordinator.ReadingOptions(rawValue: 0), 51 | error: &error) { newURL in 52 | do { 53 | try data.write(to: newURL, options: [.atomic, additionalFileWritingOptions]) 54 | success = true 55 | } catch let error as NSError { 56 | NSLog("SwiftyMessenger: Error on writeMessage \(error.description)") 57 | success = false 58 | } 59 | } 60 | return success 61 | } 62 | 63 | override open func messageForIdentifier(identifier: String?) -> Any? { 64 | guard let identifier = identifier, let filePath = filePath(forIdentifier: identifier) else { 65 | return nil 66 | } 67 | let fileURL = URL(fileURLWithPath: filePath) 68 | let fileCoordinator = NSFileCoordinator(filePresenter: nil) 69 | var error: NSError? 70 | var data: NSData? = nil 71 | fileCoordinator.coordinate(readingItemAt: fileURL, 72 | options: NSFileCoordinator.ReadingOptions(rawValue: 0), 73 | error: &error) { newURL in 74 | data = NSData(contentsOf: newURL) 75 | } 76 | guard let filledData = data as Data? else { 77 | return nil 78 | } 79 | let message = NSKeyedUnarchiver.unarchiveObject(with: filledData) 80 | return message 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /Source/MessengerFileTransiting.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerFileTransiting.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | Interface for classes wishing to support the transiting of data 27 | between container app and extension. Transiting is defined as passage between two points, and in this 28 | case it involves both the reading and writing of messages as well as the deletion of message 29 | contents. 30 | */ 31 | public protocol FileTransiting { 32 | 33 | /** 34 | Responsible for writing a given message object in a persisted format for a given 35 | identifier. The method should return true if the message was successfully saved. The message object 36 | may be nil, in which case true should also be returned. Returning true from this method results in a 37 | notification being fired which will trigger the corresponding listener block for the given 38 | identifier. 39 | 40 | - parameter message: The message dictionary to be passed. 41 | This dictionary may be nil. In this the method should return true. 42 | - parameter identifier: The identifier for the message 43 | - return: `true` indicating that a notification should be sent and `false` otherwise 44 | */ 45 | func writeMessage(message: Any?, identifier: String) -> Bool 46 | 47 | /** 48 | For reading and returning the contents of a given message. It should 49 | understand the structure of messages saved by the implementation of the above writeMessage 50 | method and be able to read those messages and return their contents. 51 | 52 | - parameter identifier: The identifier for the message 53 | - return: Optional message object 54 | */ 55 | func messageForIdentifier(identifier: String?) -> Any? 56 | 57 | /** 58 | Clear the persisted contents of a specific message with a given identifier. 59 | 60 | - parameter identifier: The identifier for the message 61 | */ 62 | func deleteContent(withIdentifier identifier: String?) 63 | 64 | /** 65 | Clear the contents of all messages passed to the Messenger. 66 | */ 67 | func deleteContentForAllMessages() 68 | 69 | } 70 | 71 | /** 72 | Protocol used to notify container app and extension with identifier and message. 73 | */ 74 | public protocol TransitingDelegate { 75 | 76 | /** 77 | Notifier between two sides. 78 | 79 | - parameter identifier: The identifier for the message 80 | - parameter message: Message dictionary 81 | */ 82 | func notifyListenerForMessage(withIdentifier identifier: String?, message: Any?) 83 | 84 | } 85 | 86 | open class MessengerFileTransiting: FileTransiting { 87 | 88 | internal var applicationGroupIdentifier: String! 89 | internal var directory: String? 90 | internal var fileManager: FileManager! 91 | 92 | internal convenience init() { 93 | self.init(withApplicationGroupIdentifier: "dev.messenger.nonDesignatedInitializer", directory: nil) 94 | } 95 | 96 | /** 97 | Initializer. 98 | 99 | - parameter identifier: An application group identifier 100 | - parameter directory: An optional directory to read/write messages 101 | */ 102 | public init(withApplicationGroupIdentifier identifier: String?, directory: String?) { 103 | applicationGroupIdentifier = identifier 104 | self.directory = directory 105 | fileManager = FileManager() 106 | } 107 | 108 | // MARK: File Operation Methods 109 | 110 | internal func messagePassingDirectoryPath() -> String? { 111 | guard let appGroupContainer = fileManager.containerURL(forSecurityApplicationGroupIdentifier: applicationGroupIdentifier) else { 112 | return nil 113 | } 114 | let appGroupContainerPath = appGroupContainer.path 115 | var directoryPath = appGroupContainerPath 116 | if let directory = directory { 117 | directoryPath = appGroupContainerPath.appendingPathComponent(path: directory) 118 | } 119 | do { 120 | try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil) 121 | } catch let error as NSError { 122 | NSLog("SwiftyMessenger: Error on messagePassingDirectoryPath \(error.description)") 123 | return nil 124 | } 125 | return directoryPath 126 | } 127 | 128 | internal func filePath(forIdentifier identifier: String) -> String? { 129 | if identifier.isEmpty { 130 | return nil 131 | } 132 | let directoryPath = messagePassingDirectoryPath() 133 | let fileName = String(format: "%@.archive", identifier) 134 | let filePath = directoryPath?.appendingPathComponent(path: fileName) 135 | return filePath 136 | } 137 | 138 | // MARK: FileTransiting 139 | 140 | open func writeMessage(message: Any?, identifier: String) -> Bool { 141 | if identifier.isEmpty { 142 | return false 143 | } 144 | guard let message = message else { 145 | return false 146 | } 147 | let data = NSKeyedArchiver.archivedData(withRootObject: message) as NSData 148 | guard let filePath = self.filePath(forIdentifier: identifier) else { 149 | return false 150 | } 151 | let success = data.write(toFile: filePath, atomically: true) 152 | if !success { 153 | return false 154 | } 155 | return true 156 | } 157 | 158 | open func messageForIdentifier(identifier: String?) -> Any? { 159 | guard let identifier = identifier else { 160 | return nil 161 | } 162 | guard let filePath = self.filePath(forIdentifier: identifier) else { 163 | return nil 164 | } 165 | do { 166 | let data = try NSData(contentsOfFile: filePath) as Data 167 | let message = NSKeyedUnarchiver.unarchiveObject(with: data) 168 | return message 169 | } catch let error as NSError { 170 | NSLog("SwiftyMessenger: Error on messageForIdentifier \(error.description)") 171 | return nil 172 | } 173 | } 174 | 175 | open func deleteContent(withIdentifier identifier: String?) { 176 | guard let identifier = identifier else { 177 | NSLog("SwiftyMessenger: Can't delete content, given identifier is nil") 178 | return 179 | } 180 | do { 181 | try fileManager.removeItem(atPath: identifier) 182 | } catch let error as NSError { 183 | NSLog("SwiftyMessenger: Error on deleteContent \(error.description)") 184 | } 185 | } 186 | 187 | open func deleteContentForAllMessages() { 188 | guard let _ = directory, let directoryPath = messagePassingDirectoryPath() else { 189 | return 190 | } 191 | do { 192 | let messageFiles = try fileManager.contentsOfDirectory(atPath: directoryPath) 193 | for path in messageFiles { 194 | let filePath = directoryPath.appendingPathComponent(path: path) 195 | do { 196 | try fileManager.removeItem(atPath: filePath) 197 | } catch let error as NSError { 198 | NSLog("SwiftyMessenger: Error on deleteContentForAllMessages \(error.description)") 199 | } 200 | } 201 | } catch let error as NSError { 202 | NSLog("SwiftyMessenger: Error on deleteContentForAllMessages \(error.description)") 203 | } 204 | } 205 | 206 | } 207 | -------------------------------------------------------------------------------- /Source/MessengerSession.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerSession.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | import WatchConnectivity 26 | 27 | open class MessengerSession: NSObject { 28 | 29 | private var session: WCSession! 30 | private var messenger: Messenger! 31 | public static let shared = MessengerSession() 32 | 33 | private override init() { 34 | super.init() 35 | messenger = Messenger(withApplicationGroupIdentifier: nil, directory: nil) 36 | session = WCSession.default 37 | session.delegate = self 38 | } 39 | 40 | open func activateSession() { 41 | session.activate() 42 | } 43 | 44 | open func notifyListenerForMessage(withIdentifier identifier: String?, message: Any?) { 45 | messenger.notifyListenerForMessage(withIdentifier: identifier, message: message) 46 | } 47 | 48 | open func passMessage(message: Any?, identifier: String?) { 49 | messenger.passMessage(message: message, identifier: identifier) 50 | } 51 | 52 | open func messageForIdentifier(identifier: String?) -> Any? { 53 | return messenger.messageForIdentifier(identifier: identifier) 54 | } 55 | 56 | open func clearMessageContents(identifer: String?) { 57 | messenger.clearMessageContents(identifer: identifer) 58 | } 59 | 60 | open func clearAllMessageContents() { 61 | messenger.clearAllMessageContents() 62 | } 63 | 64 | open func listenForMessage(withIdentifier identifier: String?, listener: @escaping ((Any) -> Void)) { 65 | messenger.listenForMessage(withIdentifier: identifier, listener: listener) 66 | } 67 | 68 | open func stopListeningForMessage(withIdentifier identifier: String?) { 69 | messenger.stopListeningForMessage(withIdentifier: identifier) 70 | } 71 | 72 | } 73 | 74 | extension MessengerSession: WCSessionDelegate { 75 | 76 | @available(watchOSApplicationExtension 2.2, *) 77 | @available(iOS 9.3, *) 78 | public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 79 | 80 | } 81 | 82 | #if os(iOS) 83 | public func sessionDidBecomeInactive(_ session: WCSession) { 84 | 85 | } 86 | #endif 87 | 88 | #if os(iOS) 89 | public func sessionDidDeactivate(_ session: WCSession) { 90 | 91 | } 92 | #endif 93 | 94 | public func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { 95 | for identifier in message.keys { 96 | if let data = message[identifier] as? Data { 97 | let message = NSKeyedUnarchiver.unarchiveObject(with: data) 98 | messenger.notifyListenerForMessage(withIdentifier: identifier, message: message) 99 | } 100 | } 101 | } 102 | 103 | public func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) { 104 | for identifier in applicationContext.keys { 105 | if let data = applicationContext[identifier] as? Data { 106 | let message = NSKeyedUnarchiver.unarchiveObject(with: data) 107 | messenger.notifyListenerForMessage(withIdentifier: identifier, message: message) 108 | } 109 | } 110 | } 111 | 112 | public func session(_ session: WCSession, didReceive file: WCSessionFile) { 113 | guard let identifier = file.metadata?["identifier"] as? String else { 114 | return 115 | } 116 | do { 117 | let data = try NSData(contentsOf: file.fileURL) as Data 118 | guard let message = NSKeyedUnarchiver.unarchiveObject(with: data) else { 119 | return 120 | } 121 | messenger.notifyListenerForMessage(withIdentifier: identifier, message: message) 122 | let messengerFileTransiting = messenger.transitingDelegate as? MessengerFileTransiting 123 | let archivedData = NSKeyedArchiver.archivedData(withRootObject: message) as NSData 124 | guard let filePath = messengerFileTransiting?.filePath(forIdentifier: identifier) else { 125 | return 126 | } 127 | archivedData.write(to: URL(fileURLWithPath: filePath), atomically: true) 128 | } catch let error as NSError { 129 | NSLog("SwiftyMessenger: Error on didReceive file \(error.description)") 130 | } 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /Source/MessengerSessionContextTransiting.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerSessionContextTransiting.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | import WatchConnectivity 26 | 27 | /** 28 | Provides support for the WatchConnectivity framework's Application Context message 29 | reading and writing ability. This class will pass it's messages directly via the 30 | -updateApplicationContext method, and read message values from application context. 31 | */ 32 | open class MessengerSessionContextTransiting: MessengerFileTransiting { 33 | 34 | private var session: WCSession! 35 | private var lastContext: [String: Any]? 36 | 37 | override init(withApplicationGroupIdentifier identifier: String?, directory: String?) { 38 | super.init(withApplicationGroupIdentifier: identifier, directory: directory) 39 | session = WCSession.default 40 | } 41 | 42 | override open func writeMessage(message: Any?, identifier: String) -> Bool { 43 | if identifier.isEmpty { 44 | return false 45 | } 46 | if !WCSession.isSupported() { 47 | return false 48 | } 49 | guard let message = message else { 50 | return false 51 | } 52 | let data = NSKeyedArchiver.archivedData(withRootObject: message) as Data 53 | let applicationContext = session.applicationContext 54 | if lastContext == nil { 55 | lastContext = applicationContext 56 | } 57 | var currentContext = applicationContext 58 | applicationContext.forEach { (arg) in 59 | let (key, value) = arg 60 | currentContext[key] = value 61 | } 62 | currentContext[identifier] = data 63 | lastContext = currentContext 64 | do { 65 | try session.updateApplicationContext(currentContext) 66 | } catch let error as NSError { 67 | NSLog("SwiftyMessenger: Error on writeMessage \(error.description)") 68 | } 69 | return false 70 | } 71 | 72 | override open func messageForIdentifier(identifier: String?) -> Any? { 73 | guard let identifier = identifier else { 74 | return nil 75 | } 76 | let receivedContext = session.receivedApplicationContext 77 | guard let data = receivedContext[identifier] as? Data else { 78 | let currentContext = session.applicationContext 79 | guard let dataFromContext = currentContext[identifier] as? Data else { 80 | return nil 81 | } 82 | let message = NSKeyedUnarchiver.unarchiveObject(with: dataFromContext) 83 | return message 84 | } 85 | let message = NSKeyedUnarchiver.unarchiveObject(with: data) 86 | return message 87 | } 88 | 89 | override open func deleteContent(withIdentifier identifier: String?) { 90 | guard let identifier = identifier, var lastContext = lastContext else { 91 | return 92 | } 93 | lastContext[identifier] = nil 94 | var currentContext = session.applicationContext 95 | currentContext[identifier] = nil 96 | do { 97 | try session.updateApplicationContext(currentContext) 98 | } catch let error as NSError { 99 | NSLog("SwiftyMessenger: Error on deleteContent \(error.description)") 100 | } 101 | } 102 | 103 | override open func deleteContentForAllMessages() { 104 | guard var lastContext = lastContext else { 105 | return 106 | } 107 | lastContext.removeAll() 108 | do { 109 | try session.updateApplicationContext([String: Any]()) 110 | } catch let error as NSError { 111 | NSLog("SwiftyMessenger: Error on deleteContentForAllMessages \(error.description)") 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /Source/MessengerSessionFileTransiting.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerSessionFileTransiting.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | import WatchConnectivity 26 | 27 | /** 28 | Provides support for the WatchConnectivity framework's file transfer ability. This class 29 | will behave very similar to the MessengerFileTransiting implementation, meaning it will archive 30 | messages to disk as files and send them via the WatchConnectivity framework's -transferFile API. 31 | */ 32 | open class MessengerSessionFileTransiting: MessengerFileTransiting { 33 | 34 | private var session: WCSession! 35 | 36 | override init(withApplicationGroupIdentifier identifier: String?, directory: String?) { 37 | super.init(withApplicationGroupIdentifier: identifier, directory: directory) 38 | session = WCSession.default 39 | } 40 | 41 | override open func writeMessage(message: Any?, identifier: String) -> Bool { 42 | if identifier.isEmpty { 43 | return false 44 | } 45 | if !WCSession.isSupported() { 46 | return false 47 | } 48 | guard let message = message else { 49 | return false 50 | } 51 | let data = NSKeyedArchiver.archivedData(withRootObject: message) 52 | var tempDir = messagePassingDirectoryPath() ?? "" 53 | if tempDir.isEmpty { 54 | tempDir = NSTemporaryDirectory() 55 | } 56 | guard let tempURL = NSURL(fileURLWithPath: tempDir).appendingPathComponent(identifier) else { 57 | return false 58 | } 59 | do { 60 | try data.write(to: tempURL) 61 | session.transferFile(tempURL, metadata: ["identifier": identifier]) 62 | } catch let error as NSError { 63 | NSLog("SwiftyMessenger: Error on writeMessage \(error.description)") 64 | } 65 | return false 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /Source/MessengerSessionMessageTransiting.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerSessionMessageTransiting.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | import WatchConnectivity 26 | 27 | /** 28 | Provides support for the WatchConnectivity framework's real time message passing ability. 29 | */ 30 | open class MessengerSessionMessageTransiting: MessengerFileTransiting { 31 | 32 | private var session: WCSession! 33 | 34 | override init(withApplicationGroupIdentifier identifier: String?, directory: String?) { 35 | super.init(withApplicationGroupIdentifier: identifier, directory: directory) 36 | session = WCSession.default 37 | } 38 | 39 | override func messagePassingDirectoryPath() -> String? { 40 | return nil 41 | } 42 | 43 | override open func writeMessage(message: Any?, identifier: String) -> Bool { 44 | if identifier.isEmpty { 45 | return false 46 | } 47 | guard let message = message else { 48 | return false 49 | } 50 | let data = NSKeyedArchiver.archivedData(withRootObject: message) 51 | if session.isReachable { 52 | session.sendMessage([identifier: data], replyHandler: nil) { error in 53 | let nsError = error as NSError 54 | NSLog("SwiftyMessenger: Error on writeMessage \(nsError.description)") 55 | } 56 | } 57 | return true 58 | } 59 | 60 | override open func messageForIdentifier(identifier: String?) -> Any? { 61 | return nil 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /Source/String+Path.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+Path.swift 3 | // SwiftyMessenger 4 | // 5 | // Copyright © 2018 Abdullah Selek 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 | extension String { 26 | 27 | func appendingPathComponent(path: String) -> String { 28 | let nsSt = self as NSString 29 | return nsSt.appendingPathComponent(path) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Source/SwiftyMessenger.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftyMessenger.h 3 | // SwiftyMessenger 4 | // 5 | // Created by Abdullah Selek on 15.05.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SwiftyMessenger. 12 | FOUNDATION_EXPORT double SwiftyMessengerVersionNumber; 13 | 14 | //! Project version string for SwiftyMessenger. 15 | FOUNDATION_EXPORT const unsigned char SwiftyMessengerVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SwiftyMessenger-iOSTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SwiftyMessenger-iOSTests/SwiftyMessenger_iOSTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessengerFileTransitingTests.swift 3 | // SwiftyMessengerTests 4 | // 5 | // Created by Abdullah Selek on 16.05.18. 6 | // Copyright © 2018 Abdullah Selek. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | @testable import SwiftyMessenger 12 | 13 | class MessengerFileTransitingTests: XCTestCase { 14 | 15 | var fileTransiting: MessengerFileTransiting! 16 | 17 | override func setUp() { 18 | super.setUp() 19 | fileTransiting = MessengerFileTransiting(withApplicationGroupIdentifier: "com.abdullahselek.SwiftyGroup", directory: "tests") 20 | } 21 | 22 | func testInit() { 23 | XCTAssertNotNil(MessengerFileTransiting(), "MessengerFileTransiting default initialization failed!") 24 | } 25 | 26 | func testInitWithParameter() { 27 | XCTAssertNotNil(fileTransiting, "MessengerFileTransiting initialization with parameters failed!") 28 | } 29 | 30 | func testMessagePassingDirectoryPath() { 31 | XCTAssertNotNil(fileTransiting.messagePassingDirectoryPath()) 32 | } 33 | 34 | func testFilePath_whenIdentifierEmpty() { 35 | XCTAssertNil(fileTransiting.filePath(forIdentifier: "")) 36 | } 37 | 38 | func testFilePath_whenIdentifierNotEmpty() { 39 | // because of testing framework there is no app group available 40 | XCTAssertNotNil(fileTransiting.filePath(forIdentifier: "file1")) 41 | } 42 | 43 | override func tearDown() { 44 | fileTransiting = nil 45 | super.tearDown() 46 | } 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /SwiftyMessenger.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = 'SwiftyMessenger' 4 | s.version = '0.4.0' 5 | s.summary = 'Swift toolkit for passing messages between iOS apps and extensions.' 6 | s.homepage = 'https://github.com/abdullahselek/SwiftyMessenger' 7 | s.license = { 8 | :type => 'MIT', 9 | :file => 'LICENSE' 10 | } 11 | s.author = { 12 | 'Abdullah Selek' => 'abdullahselek@gmail.com' 13 | } 14 | s.source = { 15 | :git => 'https://github.com/abdullahselek/SwiftyMessenger.git', 16 | :tag => s.version.to_s 17 | } 18 | s.ios.deployment_target = '10.0' 19 | s.watchos.deployment_target = '3.0' 20 | s.source_files = 'Source/*.swift' 21 | s.requires_arc = true 22 | s.swift_versions = ['5.0', '5.1', '5.2', '5.3'] 23 | 24 | end 25 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcodeproj/xcshareddata/xcschemes/SwiftyMessenger-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 51 | 52 | 62 | 63 | 69 | 70 | 71 | 72 | 78 | 79 | 85 | 86 | 87 | 88 | 90 | 91 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcodeproj/xcshareddata/xcschemes/SwiftyMessenger-iOSTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 37 | 38 | 44 | 45 | 47 | 48 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcodeproj/xcshareddata/xcschemes/SwiftyMessenger-watchOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftyMessenger.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /scripts/build-framework.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | BASE_PWD="$PWD" 6 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 7 | OUTPUT_DIR=$( mktemp -d ) 8 | COMMON_SETUP="-workspace ${SCRIPT_DIR}/../SwiftyMessenger.xcworkspace -scheme SwiftyMessenger-iOS -configuration Release -quiet SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES" 9 | 10 | # iOS 11 | DERIVED_DATA_PATH=$( mktemp -d ) 12 | xcrun xcodebuild build \ 13 | $COMMON_SETUP \ 14 | -derivedDataPath "${DERIVED_DATA_PATH}" \ 15 | -destination 'generic/platform=iOS' 16 | 17 | mkdir -p "${OUTPUT_DIR}/iphoneos" 18 | cp -r "${DERIVED_DATA_PATH}/Build/Products/Release-iphoneos/SwiftyMessenger.framework" "${OUTPUT_DIR}/iphoneos" 19 | rm -rf "${DERIVED_DATA_PATH}" 20 | 21 | # iOS Simulator 22 | DERIVED_DATA_PATH=$( mktemp -d ) 23 | xcrun xcodebuild build \ 24 | $COMMON_SETUP \ 25 | -derivedDataPath "${DERIVED_DATA_PATH}" \ 26 | -destination 'generic/platform=iOS Simulator' 27 | 28 | mkdir -p "${OUTPUT_DIR}/iphonesimulator" 29 | cp -r "${DERIVED_DATA_PATH}/Build/Products/Release-iphonesimulator/SwiftyMessenger.framework" "${OUTPUT_DIR}/iphonesimulator" 30 | rm -rf "${DERIVED_DATA_PATH}" 31 | 32 | # XCFRAMEWORK 33 | xcrun xcodebuild -create-xcframework \ 34 | -framework "${OUTPUT_DIR}/iphoneos/SwiftyMessenger.framework" \ 35 | -framework "${OUTPUT_DIR}/iphonesimulator/SwiftyMessenger.framework" \ 36 | -output ${OUTPUT_DIR}/SwiftyMessenger.xcframework 37 | 38 | ditto -c -k --keepParent ${OUTPUT_DIR}/SwiftyMessenger.xcframework SwiftyMessenger.xcframework.zip 39 | 40 | echo "✔️ SwiftyMessenger.xcframework" 41 | 42 | rm -rf ${OUTPUT_DIR} 43 | 44 | cd ${BASE_PWD} 45 | --------------------------------------------------------------------------------