diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 69c219d4..00000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-# .circleci/config.yml
-
-# Specify the config version - version 2 is latest.
-version: 2
-
-# Define the jobs for the current project.
-jobs:
- build-and-test:
-
- environment:
- - DESTINATION: "platform=iOS Simulator,name=iPhone 11 Pro"
-
- # Specify the Xcode version to use.
- macos:
- xcode: "11.3.1"
-
- # Define the steps required to build the project.
- steps:
-
- # Get the code from the VCS provider.
- - checkout
- - run:
- name: Update Homebrew
- command: brew update
- - run:
- name: Bootstrap Carthage
- command: carthage bootstrap --platform ios
- - run:
- name: Build framework
- command: xcodebuild build -project MessageKit.xcodeproj -scheme MessageKit -destination "$DESTINATION" CODE_SIGNING_REQUIRED=NO | xcpretty -c
- - run:
- name: Build and run tests
- command: xcodebuild test -project MessageKit.xcodeproj -scheme MessageKitTests -destination "$DESTINATION" CODE_SIGNING_REQUIRED=NO | xcpretty -c
- - run:
- name: Fetch CocoaPods Specs
- command: curl -sS https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash
- - run:
- name: Update Pods
- command: cd Example && pod install
- - run:
- name: Build and analyze Example
- command: xcodebuild build analyze -workspace Example/ChatExample.xcworkspace -scheme ChatExample -destination "$DESTINATION" ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | xcpretty -c
-
- # Run tests.
- #- run:
- # name: Run tests
- # command: fastlane scan
- # environment:
- # SCAN_DEVICE: iPhone 6
- # SCAN_SCHEME: WebTests
-
- # Collect XML test results data to show in the UI,
- # and save the same XML files under test-results folder
- # in the Artifacts tab.
- #- store_test_results:
- # path: test_output/report.xml
- #- store_artifacts:
- # path: /tmp/test-results
- # destination: scan-test-results
- #- store_artifacts:
- # path: ~/Library/Logs/scan
- # destination: scan-logs
-
-workflows:
- version: 2
- build-and-deploy:
- jobs:
- - build-and-test
diff --git a/.github/workflows/ci_pr_example.yml b/.github/workflows/ci_pr_example.yml
new file mode 100644
index 00000000..cf543790
--- /dev/null
+++ b/.github/workflows/ci_pr_example.yml
@@ -0,0 +1,31 @@
+name: PR Example app
+
+on: pull_request
+
+jobs:
+ tests:
+ name: Build Example app
+ runs-on: macOS-latest
+ steps:
+ - name: Checkout the Git repository
+ uses: actions/checkout@v2
+ - name: Cache Pods
+ uses: actions/cache@v1
+ with:
+ path: Example/Pods
+ key: ${{ runner.os }}-example-${{ env.cache-name }}-pods-${{ hashFiles('**/Example/Podfile.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-example-${{ env.cache-name }}-pods-
+ ${{ runner.os }}-example-${{ env.cache-name }}-
+ ${{ runner.os }}-example-
+ - name: Cache Gems
+ uses: actions/cache@v1
+ with:
+ path: vendor/bundle
+ key: ${{ runner.os }}-example-${{ env.cache-name }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-example-${{ env.cache-name }}-gems-
+ ${{ runner.os }}-example-${{ env.cache-name }}-
+ ${{ runner.os }}-example-
+ - name: Build and run example project
+ run: ./GitHubActions/build.sh example
diff --git a/.github/workflows/ci_pr_framework.yml b/.github/workflows/ci_pr_framework.yml
new file mode 100644
index 00000000..2d17fbbc
--- /dev/null
+++ b/.github/workflows/ci_pr_framework.yml
@@ -0,0 +1,22 @@
+name: PR Framework
+
+on: pull_request
+
+jobs:
+ tests:
+ name: Build Framework
+ runs-on: macOS-latest
+ steps:
+ - name: Checkout the Git repository
+ uses: actions/checkout@v2
+ - name: Cache Carthage
+ uses: actions/cache@v1
+ with:
+ path: Carthage
+ key: ${{ runner.os }}-framework-${{ env.cache-name }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-framework-${{ env.cache-name }}-carthage-
+ ${{ runner.os }}-framework-${{ env.cache-name }}-
+ ${{ runner.os }}-framework-
+ - name: Build framework
+ run: ./GitHubActions/build.sh framework
diff --git a/.github/workflows/ci_pr_tests.yml b/.github/workflows/ci_pr_tests.yml
new file mode 100644
index 00000000..65cc396d
--- /dev/null
+++ b/.github/workflows/ci_pr_tests.yml
@@ -0,0 +1,22 @@
+name: PR Tests
+
+on: pull_request
+
+jobs:
+ tests:
+ name: Run Tests
+ runs-on: macOS-latest
+ steps:
+ - name: Checkout the Git repository
+ uses: actions/checkout@v2
+ - name: Cache Carthage
+ uses: actions/cache@v1
+ with:
+ path: Carthage
+ key: ${{ runner.os }}-tests-${{ env.cache-name }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-tests-${{ env.cache-name }}-carthage-
+ ${{ runner.os }}-tests-${{ env.cache-name }}-
+ ${{ runner.os }}-tests-
+ - name: Build and run tests
+ run: ./GitHubActions/build.sh tests
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
new file mode 100644
index 00000000..5e149e68
--- /dev/null
+++ b/.github/workflows/danger.yml
@@ -0,0 +1,24 @@
+name: PR Danger
+
+on: pull_request
+
+jobs:
+ danger:
+ name: Run Danger
+ runs-on: macOS-latest
+ steps:
+ - name: Checkout the Git repository
+ uses: actions/checkout@v2
+ - name: Cache Gems
+ uses: actions/cache@v1
+ with:
+ path: vendor/bundle
+ key: ${{ runner.os }}-danger-${{ env.cache-name }}-gems-${{ hashFiles('**/Gemfile.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-danger-${{ env.cache-name }}-gems-
+ ${{ runner.os }}-danger-${{ env.cache-name }}-
+ ${{ runner.os }}-danger-
+ - name: Run build script
+ run: gem install bundler && bundle install && bundle exec danger --fail-on-errors=true
+ env:
+ DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.swift-version b/.swift-version
deleted file mode 100644
index 819e07a2..00000000
--- a/.swift-version
+++ /dev/null
@@ -1 +0,0 @@
-5.0
diff --git a/.swiftlint.yml b/.swiftlint.yml
index 5ebf9e77..f0172b38 100644
--- a/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -13,7 +13,6 @@ custom_rules:
severity: warning # violation severity. optional.
opt_in_rules:
- explicit_top_level_acl
-explicit_acl: error
explicit_top_level_acl: error
included:
- - Sources
\ No newline at end of file
+ - Sources
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 8b89d351..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-language: objective-c
-osx_image: xcode8.1
-
-env:
- global:
- - LANG=en_US.UTF-8
-
- - PROJECT="MessageKit.xcodeproj"
- - IOS_SCHEME="MessageKit"
- - IOS_SDK=iphonesimulator10.1
-
- matrix:
-
- - DESTINATION="OS=9.0,name=iPhone 6 Plus" SDK="$IOS_SDK" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="YES" POD_LINT="NO" RUN_UI_TESTS="YES"
- - DESTINATION="OS=9.1,name=iPhone 6s" SDK="$IOS_SDK" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" RUN_UI_TESTS="NO"
- - DESTINATION="OS=9.2,name=iPhone 6s" SDK="$IOS_SDK" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" RUN_UI_TESTS="NO"
- - DESTINATION="OS=9.3,name=iPad Pro" SDK="$IOS_SDK" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" RUN_UI_TESTS="NO"
-
- - DESTINATION="OS=10.0,name=iPhone 6s" SDK="$IOS_SDK" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="YES" POD_LINT="NO" RUN_UI_TESTS="YES"
- - DESTINATION="OS=10.1,name=iPhone 7" SDK="$IOS_SDK" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" RUN_UI_TESTS="NO"
-
-script:
-
-- if [ $POD_LINT == "YES" ]; then
- pod lib lint;
- fi
-
-
-- if [ $BUILD_EXAMPLE == "YES" ]; then
- xcodebuild build analyze -project Example/ChatExample.xcodeproj -scheme ChatExample -sdk "$SDK" -destination "$DESTINATION" ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | xcpretty -c;
- fi
-
-
-- if [ $RUN_TESTS == "YES" ]; then
- xcodebuild analyze test -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | xcpretty -c;
- else
- xcodebuild build analyze -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | xcpretty -c;
- fi
-
-
-- if [ $RUN_UI_TESTS == "YES" ]; then
- xcodebuild test -project Example/ChatExample.xcodeproj -scheme ChatExampleUITests -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO | xcpretty -c;
- fi
-
-
-# Build for reporting test coverage
-- if [ $RUN_TESTS == "YES" ]; then
- xcodebuild test -project MessageKit.xcodeproj -scheme MessageKit -destination "platform=iOS Simulator,name=iPhone 7" CODE_SIGNING_REQUIRED=NO;
- fi
-
-
-after_success:
-- bash <(curl -s https://codecov.io/bash)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d2120a6..806c3249 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,18 @@
The changelog for `MessageKit`. Also see the [releases](https://github.com/MessageKit/MessageKit/releases) on GitHub.
+## Upcoming release
+
+### Fixed
+
+### Added
+
+- Added option to use Photo messages with remote image URL in Example project [#1294](https://github.com/MessageKit/MessageKit/pull/1294) by [@martinpucik](https://github.com/martinpucik)
+
+### Changed
+
+- **Breaking Change** Dropped support for iOS 9 and iOS 10 [#1261](https://github.com/MessageKit/MessageKit/pull/1261) by [@kaspik](https://github.com/kaspik)
+
## 3.1.0
### Fixed
diff --git a/Dangerfile b/Dangerfile
new file mode 100644
index 00000000..3ef010fc
--- /dev/null
+++ b/Dangerfile
@@ -0,0 +1,49 @@
+#
+# MIT License
+#
+# Copyright (c) 2017-2020 MessageKit
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# This runs on CI
+mergeable_state = github.pr_json["mergeable_state"]
+
+# Make it more obvious that a PR a draft
+if mergeable_state == "draft"
+ warn("PR is marked as Draft")
+end
+
+# Mainly to encourage writing up some reasoning about the PR, rather than just leaving a title
+if github.pr_body.length < 5
+ fail("Please provide a summary in the Pull Request description")
+end
+
+declared_hashtag = github.pr_title.include?("#trivial")
+hasChangelogEntry = git.modified_files.include?("CHANGELOG.md")
+if !hasChangelogEntry && !declared_hashtag
+ fail("Please include a CHANGELOG entry. \nYou can find it at [CHANGELOG.md](https://github.com/MessageKit/MessageKit/blob/master/CHANGELOG.md).")
+end
+
+# Warn when there is a big PR
+if git.lines_of_code > 1000
+ warn("Big Pull Request - Please consider splitting up your changes into smaller Pull Requests.")
+end
+
+swiftlint.config_file = '.swiftlint.yml'
+swiftlint.lint_files inline_mode:true, fail_on_error:true
diff --git a/Example/ChatExample.xcodeproj/project.pbxproj b/Example/ChatExample.xcodeproj/project.pbxproj
index 89a85340..73778894 100644
--- a/Example/ChatExample.xcodeproj/project.pbxproj
+++ b/Example/ChatExample.xcodeproj/project.pbxproj
@@ -142,6 +142,16 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 13FCBEED2424D36900CB489F /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 882B5E7F1CF7D53600B6E160 /* Info.plist */,
+ 882B5E791CF7D53600B6E160 /* Assets.xcassets */,
+ 882B5E7A1CF7D53600B6E160 /* LaunchScreen.storyboard */,
+ );
+ path = Resources;
+ sourceTree = "";
+ };
385C2924211FF3310010B4BA /* Views */ = {
isa = PBXGroup;
children = (
@@ -172,6 +182,7 @@
385C2933211FF3670010B4BA /* Extensions */ = {
isa = PBXGroup;
children = (
+ 385C292A211FF3450010B4BA /* Settings+UserDefaults.swift */,
385C292F211FF3630010B4BA /* UIColor+Extensions.swift */,
385C2930211FF3630010B4BA /* UIViewController+Extensions.swift */,
);
@@ -259,17 +270,14 @@
children = (
882B5E781CF7D53600B6E160 /* AppDelegate.swift */,
50739F9421C5075D008CA369 /* AudioController */,
- 385C2949211FF3930010B4BA /* View Controllers */,
385C293A211FF3800010B4BA /* Data Generation */,
+ 385C2933211FF3670010B4BA /* Extensions */,
385C292E211FF3540010B4BA /* Layout */,
385C2929211FF33D0010B4BA /* Models */,
- 385C2924211FF3310010B4BA /* Views */,
+ 13FCBEED2424D36900CB489F /* Resources */,
5074EF4B2163554900D82952 /* Sounds */,
- 882B5E791CF7D53600B6E160 /* Assets.xcassets */,
- 882B5E7F1CF7D53600B6E160 /* Info.plist */,
- 882B5E7A1CF7D53600B6E160 /* LaunchScreen.storyboard */,
- 385C292A211FF3450010B4BA /* Settings+UserDefaults.swift */,
- 385C2933211FF3670010B4BA /* Extensions */,
+ 385C2949211FF3930010B4BA /* View Controllers */,
+ 385C2924211FF3310010B4BA /* Views */,
);
path = Sources;
sourceTree = "";
@@ -483,11 +491,17 @@
"${PODS_ROOT}/Target Support Files/Pods-ChatExample/Pods-ChatExample-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/InputBarAccessoryView/InputBarAccessoryView.framework",
"${BUILT_PRODUCTS_DIR}/MessageKit/MessageKit.framework",
+ "${BUILT_PRODUCTS_DIR}/PINCache/PINCache.framework",
+ "${BUILT_PRODUCTS_DIR}/PINOperation/PINOperation.framework",
+ "${BUILT_PRODUCTS_DIR}/PINRemoteImage/PINRemoteImage.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/InputBarAccessoryView.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MessageKit.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINCache.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINOperation.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINRemoteImage.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -523,7 +537,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
+ shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -647,7 +661,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -699,7 +713,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_VERSION = 5.0;
@@ -714,7 +728,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = "";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Resources/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.ChatExample;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -728,7 +742,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEVELOPMENT_TEAM = "";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Resources/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.ChatExample;
PRODUCT_NAME = "$(TARGET_NAME)";
diff --git a/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme b/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme
index 31f17b89..fec5e125 100644
--- a/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme
+++ b/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme
@@ -1,6 +1,6 @@
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ codeCoverageEnabled = "YES">
+
+
+
+
@@ -54,17 +63,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
1.9.1'
diff --git a/Example/Gemfile.lock b/Example/Gemfile.lock
new file mode 100644
index 00000000..e8faf161
--- /dev/null
+++ b/Example/Gemfile.lock
@@ -0,0 +1,90 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.2)
+ activesupport (4.2.11.1)
+ i18n (~> 0.7)
+ minitest (~> 5.1)
+ thread_safe (~> 0.3, >= 0.3.4)
+ tzinfo (~> 1.1)
+ algoliasearch (1.27.1)
+ httpclient (~> 2.8, >= 2.8.3)
+ json (>= 1.5.1)
+ atomos (0.1.3)
+ claide (1.0.3)
+ cocoapods (1.9.1)
+ activesupport (>= 4.0.2, < 5)
+ claide (>= 1.0.2, < 2.0)
+ cocoapods-core (= 1.9.1)
+ cocoapods-deintegrate (>= 1.0.3, < 2.0)
+ cocoapods-downloader (>= 1.2.2, < 2.0)
+ cocoapods-plugins (>= 1.0.0, < 2.0)
+ cocoapods-search (>= 1.0.0, < 2.0)
+ cocoapods-stats (>= 1.0.0, < 2.0)
+ cocoapods-trunk (>= 1.4.0, < 2.0)
+ cocoapods-try (>= 1.1.0, < 2.0)
+ colored2 (~> 3.1)
+ escape (~> 0.0.4)
+ fourflusher (>= 2.3.0, < 3.0)
+ gh_inspector (~> 1.0)
+ molinillo (~> 0.6.6)
+ nap (~> 1.0)
+ ruby-macho (~> 1.4)
+ xcodeproj (>= 1.14.0, < 2.0)
+ cocoapods-core (1.9.1)
+ activesupport (>= 4.0.2, < 6)
+ algoliasearch (~> 1.0)
+ concurrent-ruby (~> 1.1)
+ fuzzy_match (~> 2.0.4)
+ nap (~> 1.0)
+ netrc (~> 0.11)
+ typhoeus (~> 1.0)
+ cocoapods-deintegrate (1.0.4)
+ cocoapods-downloader (1.3.0)
+ cocoapods-plugins (1.0.0)
+ nap
+ cocoapods-search (1.0.0)
+ cocoapods-stats (1.1.0)
+ cocoapods-trunk (1.4.1)
+ nap (>= 0.8, < 2.0)
+ netrc (~> 0.11)
+ cocoapods-try (1.1.0)
+ colored2 (3.1.2)
+ concurrent-ruby (1.1.6)
+ escape (0.0.4)
+ ethon (0.12.0)
+ ffi (>= 1.3.0)
+ ffi (1.12.2)
+ fourflusher (2.3.1)
+ fuzzy_match (2.0.4)
+ gh_inspector (1.1.3)
+ httpclient (2.8.3)
+ i18n (0.9.5)
+ concurrent-ruby (~> 1.0)
+ json (2.3.0)
+ minitest (5.14.0)
+ molinillo (0.6.6)
+ nanaimo (0.2.6)
+ nap (1.1.0)
+ netrc (0.11.0)
+ ruby-macho (1.4.0)
+ thread_safe (0.3.6)
+ typhoeus (1.3.1)
+ ethon (>= 0.9.0)
+ tzinfo (1.2.6)
+ thread_safe (~> 0.1)
+ xcodeproj (1.15.0)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.2.6)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ cocoapods (~> 1.9.1)
+
+BUNDLED WITH
+ 2.1.4
diff --git a/Example/Podfile b/Example/Podfile
index 2e94b538..b8a13964 100644
--- a/Example/Podfile
+++ b/Example/Podfile
@@ -1,17 +1,18 @@
source 'https://cdn.cocoapods.org/'
-platform :ios, '9.0'
+platform :ios, '11.0'
target 'ChatExample' do
use_frameworks!
pod 'MessageKit', :path => '../'
+ pod 'SwiftLint', '~> 0.39.1'
+ pod 'PINRemoteImage', '~> 3.0.0', :subspecs => ['iOS', 'PINCache']
-target 'ChatExampleTests' do
- inherit! :search_paths
-end
-
-target 'ChatExampleUITests' do
- inherit! :search_paths
-end
+ target 'ChatExampleTests' do
+ inherit! :search_paths
+ end
+ target 'ChatExampleUITests' do
+ inherit! :search_paths
+ end
end
diff --git a/Example/Podfile.lock b/Example/Podfile.lock
index 8bd75481..9a7af340 100644
--- a/Example/Podfile.lock
+++ b/Example/Podfile.lock
@@ -4,13 +4,36 @@ PODS:
- InputBarAccessoryView/Core (4.3.2)
- MessageKit (3.1.0):
- InputBarAccessoryView (~> 4.3.0)
+ - PINCache (3.0.1-beta.8):
+ - PINCache/Arc-exception-safe (= 3.0.1-beta.8)
+ - PINCache/Core (= 3.0.1-beta.8)
+ - PINCache/Arc-exception-safe (3.0.1-beta.8):
+ - PINCache/Core
+ - PINCache/Core (3.0.1-beta.8):
+ - PINOperation (~> 1.1.1)
+ - PINOperation (1.1.2)
+ - PINRemoteImage/Core (3.0.0):
+ - PINOperation
+ - PINRemoteImage/iOS (3.0.0):
+ - PINRemoteImage/Core
+ - PINRemoteImage/PINCache (3.0.0):
+ - PINCache (= 3.0.1-beta.8)
+ - PINRemoteImage/Core
+ - SwiftLint (0.39.1)
DEPENDENCIES:
- MessageKit (from `../`)
+ - PINRemoteImage/iOS (~> 3.0.0)
+ - PINRemoteImage/PINCache (~> 3.0.0)
+ - SwiftLint (~> 0.39.1)
SPEC REPOS:
trunk:
- InputBarAccessoryView
+ - PINCache
+ - PINOperation
+ - PINRemoteImage
+ - SwiftLint
EXTERNAL SOURCES:
MessageKit:
@@ -18,8 +41,12 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
InputBarAccessoryView: 7985d418040a05fe894bd4b8328dd43ab35517c3
- MessageKit: 3beb578737a5aa2bba25cc27c7b6d6faa09af5a7
+ MessageKit: 3c593dc22f7465f74822e4a873ef3157a3e05080
+ PINCache: 534fd41d358d828dfdf227a0d327f3673a65e20b
+ PINOperation: 24b774353ca248fcf87d67b2d61eef42087c125a
+ PINRemoteImage: e2b89e19fb6e77ffc099f9d9f3b3fe1745e3f9f9
+ SwiftLint: 55e96a4a4d537d4a3156859fc1c54bd24851a046
-PODFILE CHECKSUM: 90bd12ca685503630d7fe716609f4974660ed5ee
+PODFILE CHECKSUM: cf0af8a506e2b58d4d51b99e165b58c56c26d619
COCOAPODS: 1.9.1
diff --git a/Example/Sources/Data Generation/SampleData.swift b/Example/Sources/Data Generation/SampleData.swift
index 9fa50d29..525d05da 100644
--- a/Example/Sources/Data Generation/SampleData.swift
+++ b/Example/Sources/Data Generation/SampleData.swift
@@ -36,6 +36,7 @@ final internal class SampleData {
case Text
case AttributedText
case Photo
+ case PhotoFromURL = "Photo from URL"
case Video
case Audio
case Emoji
@@ -69,6 +70,11 @@ final internal class SampleData {
var now = Date()
let messageImages: [UIImage] = [#imageLiteral(resourceName: "img1"), #imageLiteral(resourceName: "img2")]
+ let messageImageURLs: [URL] = [URL(string: "https://placekitten.com/g/200/300")!,
+ URL(string: "https://placekitten.com/g/300/300")!,
+ URL(string: "https://placekitten.com/g/300/400")!,
+ URL(string: "https://placekitten.com/g/400/400")!]
+
let emojis = [
"π",
"πππ",
@@ -143,21 +149,16 @@ final internal class SampleData {
}
func randomMessageType() -> MessageTypes {
- var messageTypes = [MessageTypes]()
- for type in MessageTypes.allCases {
- if UserDefaults.standard.bool(forKey: "\(type.rawValue)" + " Messages") {
- messageTypes.append(type)
- }
- }
- return messageTypes.random()!
+ return MessageTypes.allCases.compactMap {
+ guard UserDefaults.standard.bool(forKey: "\($0.rawValue)" + " Messages") else { return nil }
+ return $0
+ }.random()!
}
// swiftlint:disable cyclomatic_complexity
func randomMessage(allowedSenders: [MockUser]) -> MockMessage {
- let randomNumberSender = Int(arc4random_uniform(UInt32(allowedSenders.count)))
-
let uniqueID = UUID().uuidString
- let user = allowedSenders[randomNumberSender]
+ let user = allowedSenders.random()!
let date = dateAddingRandomTime()
switch randomMessageType() {
@@ -169,23 +170,21 @@ final internal class SampleData {
let attributedText = attributedString(with: randomSentence)
return MockMessage(attributedText: attributedText, user: user, messageId: uniqueID, date: date)
case .Photo:
- let randomNumberImage = Int(arc4random_uniform(UInt32(messageImages.count)))
- let image = messageImages[randomNumberImage]
+ let image = messageImages.random()!
return MockMessage(image: image, user: user, messageId: uniqueID, date: date)
+ case .PhotoFromURL:
+ let imageURL: URL = messageImageURLs.random()!
+ return MockMessage(imageURL: imageURL, user: user, messageId: uniqueID, date: date)
case .Video:
- let randomNumberImage = Int(arc4random_uniform(UInt32(messageImages.count)))
- let image = messageImages[randomNumberImage]
+ let image = messageImages.random()!
return MockMessage(thumbnail: image, user: user, messageId: uniqueID, date: date)
case .Audio:
- let randomNumberSound = Int(arc4random_uniform(UInt32(sounds.count)))
- let soundURL = sounds[randomNumberSound]
+ let soundURL = sounds.random()!
return MockMessage(audioURL: soundURL, user: user, messageId: uniqueID, date: date)
case .Emoji:
- let randomNumberEmoji = Int(arc4random_uniform(UInt32(emojis.count)))
- return MockMessage(emoji: emojis[randomNumberEmoji], user: user, messageId: uniqueID, date: date)
+ return MockMessage(emoji: emojis.random()!, user: user, messageId: uniqueID, date: date)
case .Location:
- let randomNumberLocation = Int(arc4random_uniform(UInt32(locations.count)))
- return MockMessage(location: locations[randomNumberLocation], user: user, messageId: uniqueID, date: date)
+ return MockMessage(location: locations.random()!, user: user, messageId: uniqueID, date: date)
case .Url:
return MockMessage(text: "https://github.com/MessageKit", user: user, messageId: uniqueID, date: date)
case .Phone:
@@ -193,8 +192,7 @@ final internal class SampleData {
case .Custom:
return MockMessage(custom: "Someone left the conversation", user: system, messageId: uniqueID, date: date)
case .ShareContact:
- let randomContact = Int(arc4random_uniform(UInt32(contactsToShare.count)))
- return MockMessage(contact: contactsToShare[randomContact], user: user, messageId: uniqueID, date: date)
+ return MockMessage(contact: contactsToShare.random()!, user: user, messageId: uniqueID, date: date)
}
}
// swiftlint:enable cyclomatic_complexity
diff --git a/Example/Sources/Settings+UserDefaults.swift b/Example/Sources/Extensions/Settings+UserDefaults.swift
similarity index 100%
rename from Example/Sources/Settings+UserDefaults.swift
rename to Example/Sources/Extensions/Settings+UserDefaults.swift
diff --git a/Example/Sources/Models/MockMessage.swift b/Example/Sources/Models/MockMessage.swift
index a5eb6ce1..82911b08 100644
--- a/Example/Sources/Models/MockMessage.swift
+++ b/Example/Sources/Models/MockMessage.swift
@@ -52,6 +52,11 @@ private struct ImageMediaItem: MediaItem {
self.placeholderImage = UIImage()
}
+ init(imageURL: URL) {
+ self.url = imageURL
+ self.size = CGSize(width: 240, height: 240)
+ self.placeholderImage = UIImage(imageLiteralResourceName: "image_message_placeholder")
+ }
}
private struct MockAudiotem: AudioItem {
@@ -121,6 +126,11 @@ internal struct MockMessage: MessageType {
self.init(kind: .photo(mediaItem), user: user, messageId: messageId, date: date)
}
+ init(imageURL: URL, user: MockUser, messageId: String, date: Date) {
+ let mediaItem = ImageMediaItem(imageURL: imageURL)
+ self.init(kind: .photo(mediaItem), user: user, messageId: messageId, date: date)
+ }
+
init(thumbnail: UIImage, user: MockUser, messageId: String, date: Date) {
let mediaItem = ImageMediaItem(image: thumbnail)
self.init(kind: .video(mediaItem), user: user, messageId: messageId, date: date)
diff --git a/Example/Sources/Models/MockSocket.swift b/Example/Sources/Models/MockSocket.swift
index b23c5bcf..bdf1b63f 100644
--- a/Example/Sources/Models/MockSocket.swift
+++ b/Example/Sources/Models/MockSocket.swift
@@ -76,12 +76,10 @@ final class MockSocket {
onNewMessageCode?(message)
queuedMessage = nil
} else {
- let sender = arc4random_uniform(1) % 2 == 0 ? connectedUsers.first! : connectedUsers.last!
- SampleData.shared.getMessages(count: 1, allowedSenders: [sender]) { (message) in
- queuedMessage = message.first
- }
+ let sender = connectedUsers.random()!
+ let message = SampleData.shared.randomMessage(allowedSenders: [sender])
+ queuedMessage = message
onTypingStatusCode?()
}
}
-
}
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png
diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/Contents.json b/Example/Sources/Resources/Assets.xcassets/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/Contents.json
diff --git a/Example/Sources/Assets.xcassets/Dan-Leonard.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/Dan-Leonard.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg b/Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg
similarity index 100%
rename from Example/Sources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg
rename to Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg
diff --git a/Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg b/Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg
similarity index 100%
rename from Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg
rename to Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg
diff --git a/Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg b/Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg
similarity index 100%
rename from Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg
rename to Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg
diff --git a/Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg b/Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg
similarity index 100%
rename from Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg
rename to Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg
diff --git a/Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/Tim-Cook.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/Tim-Cook.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg b/Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg
similarity index 100%
rename from Example/Sources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg
rename to Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg
diff --git a/Example/Sources/Assets.xcassets/Wu-Zhong.imageset/5061845.png b/Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/5061845.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/Wu-Zhong.imageset/5061845.png
rename to Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/5061845.png
diff --git a/Example/Sources/Assets.xcassets/Wu-Zhong.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/Wu-Zhong.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_appstore.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_appstore.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png b/Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png
rename to Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png
diff --git a/Example/Sources/Assets.xcassets/ic_at.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_at.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_at.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_at.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_at.imageset/icons8-email.png b/Example/Sources/Resources/Assets.xcassets/ic_at.imageset/icons8-email.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_at.imageset/icons8-email.png
rename to Example/Sources/Resources/Assets.xcassets/ic_at.imageset/icons8-email.png
diff --git a/Example/Sources/Assets.xcassets/ic_camera.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_camera.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_camera.imageset/icons8-camera.png b/Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/icons8-camera.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_camera.imageset/icons8-camera.png
rename to Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/icons8-camera.png
diff --git a/Example/Sources/Assets.xcassets/ic_hashtag.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_hashtag.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png b/Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png
rename to Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png
diff --git a/Example/Sources/Assets.xcassets/ic_info.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_info.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_info.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_info.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_info.imageset/icons8-info.png b/Example/Sources/Resources/Assets.xcassets/ic_info.imageset/icons8-info.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_info.imageset/icons8-info.png
rename to Example/Sources/Resources/Assets.xcassets/ic_info.imageset/icons8-info.png
diff --git a/Example/Sources/Assets.xcassets/ic_keyboard.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_keyboard.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png b/Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png
rename to Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png
diff --git a/Example/Sources/Assets.xcassets/ic_library.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_library.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_library.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_library.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png b/Example/Sources/Resources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png
rename to Example/Sources/Resources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png
diff --git a/Example/Sources/Assets.xcassets/ic_like.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_like.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_like.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_like.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_like.imageset/icons8-like_it.png b/Example/Sources/Resources/Assets.xcassets/ic_like.imageset/icons8-like_it.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_like.imageset/icons8-like_it.png
rename to Example/Sources/Resources/Assets.xcassets/ic_like.imageset/icons8-like_it.png
diff --git a/Example/Sources/Assets.xcassets/ic_map_marker.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_map_marker.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png b/Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png
rename to Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png
diff --git a/Example/Sources/Assets.xcassets/ic_mic.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_mic.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png b/Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png
rename to Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png
diff --git a/Example/Sources/Assets.xcassets/ic_send.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_send.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_send.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_send.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_send.imageset/icons8-sent.png b/Example/Sources/Resources/Assets.xcassets/ic_send.imageset/icons8-sent.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_send.imageset/icons8-sent.png
rename to Example/Sources/Resources/Assets.xcassets/ic_send.imageset/icons8-sent.png
diff --git a/Example/Sources/Assets.xcassets/ic_typing.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_typing.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png b/Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png
rename to Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png
diff --git a/Example/Sources/Assets.xcassets/ic_up.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_up.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_up.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/ic_up.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png b/Example/Sources/Resources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png
rename to Example/Sources/Resources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png
diff --git a/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/Contents.json
new file mode 100644
index 00000000..ade8d418
--- /dev/null
+++ b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "image_message_placeholder.pdf",
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/image_message_placeholder.pdf b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/image_message_placeholder.pdf
new file mode 100644
index 00000000..69de86ee
Binary files /dev/null and b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/image_message_placeholder.pdf differ
diff --git a/Example/Sources/Assets.xcassets/img1.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/img1.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/img1.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/img1.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg b/Example/Sources/Resources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg
similarity index 100%
rename from Example/Sources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg
rename to Example/Sources/Resources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg
diff --git a/Example/Sources/Assets.xcassets/img2.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/img2.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/img2.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/img2.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg b/Example/Sources/Resources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg
similarity index 100%
rename from Example/Sources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg
rename to Example/Sources/Resources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg
diff --git a/Example/Sources/Assets.xcassets/mklogo.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/mklogo.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/mklogo.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/mklogo.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/mklogo.imageset/mklogo.png b/Example/Sources/Resources/Assets.xcassets/mklogo.imageset/mklogo.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/mklogo.imageset/mklogo.png
rename to Example/Sources/Resources/Assets.xcassets/mklogo.imageset/mklogo.png
diff --git a/Example/Sources/Assets.xcassets/mkorglogo.imageset/30243544.png b/Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/30243544.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/mkorglogo.imageset/30243544.png
rename to Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/30243544.png
diff --git a/Example/Sources/Assets.xcassets/mkorglogo.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/mkorglogo.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/pin.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/pin.imageset/Contents.json
similarity index 100%
rename from Example/Sources/Assets.xcassets/pin.imageset/Contents.json
rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/Contents.json
diff --git a/Example/Sources/Assets.xcassets/pin.imageset/pin.png b/Example/Sources/Resources/Assets.xcassets/pin.imageset/pin.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/pin.imageset/pin.png
rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/pin.png
diff --git a/Example/Sources/Assets.xcassets/pin.imageset/pin@2x.png b/Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@2x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/pin.imageset/pin@2x.png
rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@2x.png
diff --git a/Example/Sources/Assets.xcassets/pin.imageset/pin@3x.png b/Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@3x.png
similarity index 100%
rename from Example/Sources/Assets.xcassets/pin.imageset/pin@3x.png
rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@3x.png
diff --git a/Example/Sources/Base.lproj/LaunchScreen.storyboard b/Example/Sources/Resources/Base.lproj/LaunchScreen.storyboard
similarity index 100%
rename from Example/Sources/Base.lproj/LaunchScreen.storyboard
rename to Example/Sources/Resources/Base.lproj/LaunchScreen.storyboard
diff --git a/Example/Sources/Info.plist b/Example/Sources/Resources/Info.plist
similarity index 100%
rename from Example/Sources/Info.plist
rename to Example/Sources/Resources/Info.plist
diff --git a/Example/Sources/View Controllers/AdvancedExampleViewController.swift b/Example/Sources/View Controllers/AdvancedExampleViewController.swift
index 9cff3da1..a77d1bf0 100644
--- a/Example/Sources/View Controllers/AdvancedExampleViewController.swift
+++ b/Example/Sources/View Controllers/AdvancedExampleViewController.swift
@@ -26,6 +26,7 @@ import UIKit
import MapKit
import MessageKit
import InputBarAccessoryView
+import PINRemoteImage
final class AdvancedExampleViewController: ChatViewController {
@@ -353,6 +354,14 @@ extension AdvancedExampleViewController: MessagesDisplayDelegate {
accessoryView.layer.cornerRadius = accessoryView.frame.height / 2
accessoryView.backgroundColor = UIColor.primaryColor.withAlphaComponent(0.3)
}
+
+ func configureMediaMessageImageView(_ imageView: UIImageView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) {
+ if case MessageKind.photo(let media) = message.kind, let imageURL = media.url {
+ imageView.pin_setImage(from: imageURL)
+ } else {
+ imageView.pin_cancelImageDownload()
+ }
+ }
// MARK: - Location Messages
diff --git a/Example/Sources/View Controllers/AutocompleteExampleViewController.swift b/Example/Sources/View Controllers/AutocompleteExampleViewController.swift
index c4941db4..f50090aa 100644
--- a/Example/Sources/View Controllers/AutocompleteExampleViewController.swift
+++ b/Example/Sources/View Controllers/AutocompleteExampleViewController.swift
@@ -9,6 +9,7 @@
import UIKit
import MessageKit
import InputBarAccessoryView
+import PINRemoteImage
final class AutocompleteExampleViewController: ChatViewController {
@@ -336,6 +337,14 @@ extension AutocompleteExampleViewController: MessagesDisplayDelegate {
accessoryView.layer.cornerRadius = accessoryView.frame.height / 2
accessoryView.backgroundColor = UIColor.primaryColor.withAlphaComponent(0.3)
}
+
+ func configureMediaMessageImageView(_ imageView: UIImageView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) {
+ if case MessageKind.photo(let media) = message.kind, let imageURL = media.url {
+ imageView.pin_setImage(from: imageURL)
+ } else {
+ imageView.pin_cancelImageDownload()
+ }
+ }
}
// MARK: - MessagesLayoutDelegate
diff --git a/Example/Sources/View Controllers/BasicExampleViewController.swift b/Example/Sources/View Controllers/BasicExampleViewController.swift
index 98e81d55..dec927c7 100644
--- a/Example/Sources/View Controllers/BasicExampleViewController.swift
+++ b/Example/Sources/View Controllers/BasicExampleViewController.swift
@@ -25,6 +25,7 @@
import UIKit
import MapKit
import MessageKit
+import PINRemoteImage
final class BasicExampleViewController: ChatViewController {
override func configureMessageCollectionView() {
@@ -71,6 +72,14 @@ extension BasicExampleViewController: MessagesDisplayDelegate {
let avatar = SampleData.shared.getAvatarFor(sender: message.sender)
avatarView.set(avatar: avatar)
}
+
+ func configureMediaMessageImageView(_ imageView: UIImageView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) {
+ if case MessageKind.photo(let media) = message.kind, let imageURL = media.url {
+ imageView.pin_setImage(from: imageURL)
+ } else {
+ imageView.pin_cancelImageDownload()
+ }
+ }
// MARK: - Location Messages
diff --git a/Example/Sources/View Controllers/ChatViewController.swift b/Example/Sources/View Controllers/ChatViewController.swift
index 71c853ed..aef82746 100644
--- a/Example/Sources/View Controllers/ChatViewController.swift
+++ b/Example/Sources/View Controllers/ChatViewController.swift
@@ -1,7 +1,7 @@
/*
MIT License
-Copyright (c) 2017-2019 MessageKit
+Copyright (c) 2017-2020 MessageKit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -28,24 +28,30 @@ import InputBarAccessoryView
/// A base class for the example controllers
class ChatViewController: MessagesViewController, MessagesDataSource {
-
- override var preferredStatusBarStyle: UIStatusBarStyle {
- return .lightContent
- }
-
- /// The `BasicAudioController` controll the AVAudioPlayer state (play, pause, stop) and udpate audio cell UI accordingly.
- open lazy var audioController = BasicAudioController(messageCollectionView: messagesCollectionView)
- var messageList: [MockMessage] = []
+ // MARK: - Public properties
+
+ /// The `BasicAudioController` controll the AVAudioPlayer state (play, pause, stop) and udpate audio cell UI accordingly.
+ lazy var audioController = BasicAudioController(messageCollectionView: messagesCollectionView)
+
+ lazy var messageList: [MockMessage] = []
- let refreshControl = UIRefreshControl()
-
- let formatter: DateFormatter = {
+ private(set) lazy var refreshControl: UIRefreshControl = {
+ let control = UIRefreshControl()
+ control.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged)
+ return control
+ }()
+
+ // MARK: - Private properties
+
+ private let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
return formatter
}()
-
+
+ // MARK: - Lifecycle
+
override func viewDidLoad() {
super.viewDidLoad()
@@ -69,6 +75,10 @@ class ChatViewController: MessagesViewController, MessagesDataSource {
MockSocket.shared.disconnect()
audioController.stopAnyOngoingPlaying()
}
+
+ override var preferredStatusBarStyle: UIStatusBarStyle {
+ return .lightContent
+ }
func loadFirstMessages() {
DispatchQueue.global(qos: .userInitiated).async {
@@ -83,8 +93,7 @@ class ChatViewController: MessagesViewController, MessagesDataSource {
}
}
- @objc
- func loadMoreMessages() {
+ @objc func loadMoreMessages() {
DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 1) {
SampleData.shared.getMessages(count: 20) { messages in
DispatchQueue.main.async {
@@ -104,8 +113,7 @@ class ChatViewController: MessagesViewController, MessagesDataSource {
scrollsToBottomOnKeyboardBeginsEditing = true // default false
maintainPositionOnKeyboardFrameChanged = true // default false
- messagesCollectionView.addSubview(refreshControl)
- refreshControl.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged)
+ messagesCollectionView.refreshControl = refreshControl
}
func configureMessageInputBar() {
@@ -143,50 +151,46 @@ class ChatViewController: MessagesViewController, MessagesDataSource {
return messagesCollectionView.indexPathsForVisibleItems.contains(lastIndexPath)
}
-
+
// MARK: - MessagesDataSource
-
+
func currentSender() -> SenderType {
return SampleData.shared.currentSender
}
-
+
func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int {
return messageList.count
}
-
+
func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
return messageList[indexPath.section]
}
-
+
func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
if indexPath.section % 3 == 0 {
return NSAttributedString(string: MessageKitDateFormatter.shared.string(from: message.sentDate), attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedString.Key.foregroundColor: UIColor.darkGray])
}
return nil
}
-
+
func cellBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
-
return NSAttributedString(string: "Read", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedString.Key.foregroundColor: UIColor.darkGray])
}
-
+
func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
let name = message.sender.displayName
return NSAttributedString(string: name, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption1)])
}
-
+
func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
-
let dateString = formatter.string(from: message.sentDate)
return NSAttributedString(string: dateString, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
}
-
}
// MARK: - MessageCellDelegate
extension ChatViewController: MessageCellDelegate {
-
func didTapAvatar(in cell: MessageCollectionViewCell) {
print("Avatar tapped")
}
@@ -261,7 +265,6 @@ extension ChatViewController: MessageCellDelegate {
// MARK: - MessageLabelDelegate
extension ChatViewController: MessageLabelDelegate {
-
func didSelectAddress(_ addressComponents: [String: String]) {
print("Address Selected: \(addressComponents)")
}
@@ -293,15 +296,12 @@ extension ChatViewController: MessageLabelDelegate {
func didSelectCustom(_ pattern: String, match: String?) {
print("Custom data detector patter selected: \(pattern)")
}
-
}
// MARK: - MessageInputBarDelegate
extension ChatViewController: InputBarAccessoryViewDelegate {
-
func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) {
-
// Here we can parse for which substrings were autocompleted
let attributedText = messageInputBar.inputTextView.attributedText!
let range = NSRange(location: 0, length: attributedText.length)
diff --git a/Example/Sources/View Controllers/LaunchViewController.swift b/Example/Sources/View Controllers/LaunchViewController.swift
index 50794115..fc25609b 100644
--- a/Example/Sources/View Controllers/LaunchViewController.swift
+++ b/Example/Sources/View Controllers/LaunchViewController.swift
@@ -46,16 +46,12 @@ final internal class LaunchViewController: UITableViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
- if #available(iOS 11.0, *) {
- navigationController?.navigationBar.prefersLargeTitles = true
- }
+ navigationController?.navigationBar.prefersLargeTitles = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
- if #available(iOS 11.0, *) {
- navigationController?.navigationBar.prefersLargeTitles = false
- }
+ navigationController?.navigationBar.prefersLargeTitles = false
}
// MARK: - UITableViewDataSource
@@ -100,9 +96,7 @@ final internal class LaunchViewController: UITableViewController {
func openURL(_ url: URL) {
let webViewController = SFSafariViewController(url: url)
- if #available(iOS 10.0, *) {
- webViewController.preferredControlTintColor = .primaryColor
- }
+ webViewController.preferredControlTintColor = .primaryColor
present(webViewController, animated: true, completion: nil)
}
}
diff --git a/Example/Sources/View Controllers/NavigationController.swift b/Example/Sources/View Controllers/NavigationController.swift
index cc2d7eb2..c47cace5 100644
--- a/Example/Sources/View Controllers/NavigationController.swift
+++ b/Example/Sources/View Controllers/NavigationController.swift
@@ -36,9 +36,7 @@ final class NavigationController: UINavigationController {
navigationBar.tintColor = .white
navigationBar.barTintColor = .primaryColor
navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
- if #available(iOS 11.0, *) {
- navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
- }
+ navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
navigationBar.shadowImage = UIImage()
navigationBar.setBackgroundImage(UIImage(), for: .default)
view.backgroundColor = .primaryColor
@@ -50,17 +48,13 @@ final class NavigationController: UINavigationController {
navigationBar.barTintColor = .primaryColor
navigationBar.tintColor = .white
navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
- if #available(iOS 11.0, *) {
- navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
- }
+ navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
} else if style == .lightContent {
navigationBar.shadowImage = nil
navigationBar.barTintColor = .white
navigationBar.tintColor = UIColor(red: 0, green: 0.5, blue: 1, alpha: 1)
navigationBar.titleTextAttributes = [.foregroundColor: UIColor.black]
- if #available(iOS 11.0, *) {
- navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.black]
- }
+ navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.black]
}
}
diff --git a/Example/Sources/View Controllers/SettingsViewController.swift b/Example/Sources/View Controllers/SettingsViewController.swift
index 92235e52..137e1f3a 100644
--- a/Example/Sources/View Controllers/SettingsViewController.swift
+++ b/Example/Sources/View Controllers/SettingsViewController.swift
@@ -33,7 +33,7 @@ final internal class SettingsViewController: UITableViewController {
return .lightContent
}
- let cells = ["Mock messages count", "Text Messages", "AttributedText Messages", "Photo Messages", "Video Messages", "Audio Messages", "Emoji Messages", "Location Messages", "Url Messages", "Phone Messages", "ShareContact Messages"]
+ let cells = ["Mock messages count", "Text Messages", "AttributedText Messages", "Photo Messages", "Photo from URL Messages", "Video Messages", "Audio Messages", "Emoji Messages", "Location Messages", "Url Messages", "Phone Messages", "ShareContact Messages"]
// MARK: - Picker
diff --git a/Example/UITests/ChatExampleUITests.swift b/Example/UITests/ChatExampleUITests.swift
index d9548ce9..df4df727 100644
--- a/Example/UITests/ChatExampleUITests.swift
+++ b/Example/UITests/ChatExampleUITests.swift
@@ -28,11 +28,7 @@ final class ChatExampleUITests: XCTestCase {
continueAfterFailure = false
// UI tests must launch the application that they test.
// Doing this in setup will make sure it happens for each test method.
- if #available(iOS 9.0, *) {
- XCUIApplication().launch()
- } else {
- // Fallback on earlier versions
- }
+ XCUIApplication().launch()
// In UI tests itβs important to set the initial state
// - such as interface orientation - required for your tests before they run.
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 00000000..ce1c92bd
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,26 @@
+#
+# MIT License
+#
+# Copyright (c) 2017-2020 MessageKit
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+source 'https://rubygems.org'
+gem 'danger', '~> 6.2'
+gem 'danger-swiftlint', '~> 0.24'
\ No newline at end of file
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 00000000..f8857468
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,66 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ addressable (2.7.0)
+ public_suffix (>= 2.0.2, < 5.0)
+ claide (1.0.3)
+ claide-plugins (0.9.2)
+ cork
+ nap
+ open4 (~> 1.3)
+ colored2 (3.1.2)
+ cork (0.3.0)
+ colored2 (~> 3.1)
+ danger (6.3.1)
+ claide (~> 1.0)
+ claide-plugins (>= 0.9.2)
+ colored2 (~> 3.1)
+ cork (~> 0.1)
+ faraday (~> 0.9)
+ faraday-http-cache (~> 2.0)
+ git (~> 1.6)
+ kramdown (~> 2.0)
+ kramdown-parser-gfm (~> 1.0)
+ no_proxy_fix
+ octokit (~> 4.7)
+ terminal-table (~> 1)
+ danger-swiftlint (0.24.2)
+ danger
+ rake (> 10)
+ thor (~> 0.19)
+ faraday (0.17.3)
+ multipart-post (>= 1.2, < 3)
+ faraday-http-cache (2.0.0)
+ faraday (~> 0.8)
+ git (1.6.0)
+ rchardet (~> 1.8)
+ kramdown (2.1.0)
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ multipart-post (2.1.1)
+ nap (1.1.0)
+ no_proxy_fix (0.1.2)
+ octokit (4.17.0)
+ faraday (>= 0.9)
+ sawyer (~> 0.8.0, >= 0.5.3)
+ open4 (1.3.4)
+ public_suffix (4.0.3)
+ rake (13.0.1)
+ rchardet (1.8.0)
+ sawyer (0.8.2)
+ addressable (>= 2.3.5)
+ faraday (> 0.8, < 2.0)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ thor (0.20.3)
+ unicode-display_width (1.7.0)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ danger (~> 6.2)
+ danger-swiftlint (~> 0.24)
+
+BUNDLED WITH
+ 2.1.4
diff --git a/GitHubActions/build.sh b/GitHubActions/build.sh
new file mode 100755
index 00000000..3f998f9a
--- /dev/null
+++ b/GitHubActions/build.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+#
+# MIT License
+#
+# Copyright (c) 2017-2020 MessageKit
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+set -e
+function trap_handler {
+ echo -e "\n\nOh no! You walked directly into the slavering fangs of a lurking grue!"
+ echo "**** You have died ****"
+ exit 255
+}
+trap trap_handler INT TERM EXIT
+
+MODE="$1"
+
+if [ "$MODE" = "tests" -o "$MODE" = "all" ]; then
+ echo "Running MessageKit tests."
+ carthage bootstrap --platform ios
+ set -o pipefail && xcodebuild test -project MessageKit.xcodeproj -scheme MessageKitTests -destination "platform=iOS Simulator,name=iPhone 11 Pro" CODE_SIGNING_REQUIRED=NO | xcpretty -c
+ success="1"
+fi
+
+if [ "$MODE" = "framework" -o "$MODE" = "all" ]; then
+ echo "Building MessageKit Framework."
+ carthage bootstrap --platform ios
+ set -o pipefail && xcodebuild build -project MessageKit.xcodeproj -scheme MessageKit -destination "platform=iOS Simulator,name=iPhone 11 Pro" CODE_SIGNING_REQUIRED=NO | xcpretty -c
+ success="1"
+fi
+
+if [ "$MODE" = "example" -o "$MODE" = "all" ]; then
+ echo "Building & testing MessageKit Example app."
+ cd Example
+ gem install bundler
+ bundle check || bundle install
+ bundle exec pod install
+ set -o pipefail && xcodebuild build analyze -workspace ChatExample.xcworkspace -scheme ChatExample -destination "platform=iOS Simulator,name=iPhone 11 Pro" ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | xcpretty -c
+ success="1"
+fi
+
+if [ "$success" = "1" ]; then
+trap - EXIT
+exit 0
+fi
+
+echo "Unrecognised mode '$MODE'."
diff --git a/LICENSE.md b/LICENSE.md
index 21660f30..20cc288d 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2017-2019 MessageKit
+Copyright (c) 2017-2020 MessageKit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/MessageKit.podspec b/MessageKit.podspec
index 06b1f220..dfe3a5a0 100644
--- a/MessageKit.podspec
+++ b/MessageKit.podspec
@@ -11,17 +11,11 @@ Pod::Spec.new do |s|
s.source = { :git => 'https://github.com/MessageKit/MessageKit.git', :tag => s.version }
s.source_files = 'Sources/**/*.swift'
- s.pod_target_xcconfig = {
- "SWIFT_VERSION" => "5.0",
- }
-
s.swift_version = '5.0'
- s.ios.deployment_target = '9.0'
+ s.ios.deployment_target = '11.0'
s.ios.resource_bundle = { 'MessageKitAssets' => 'Assets/MessageKitAssets.bundle/Images' }
- s.requires_arc = true
-
s.dependency 'InputBarAccessoryView', '~> 4.3.0'
end
diff --git a/MessageKit.xcodeproj/project.pbxproj b/MessageKit.xcodeproj/project.pbxproj
index 813fa33d..d4823309 100644
--- a/MessageKit.xcodeproj/project.pbxproj
+++ b/MessageKit.xcodeproj/project.pbxproj
@@ -783,7 +783,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -838,7 +838,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_VERSION = 5.0;
@@ -865,7 +865,6 @@
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = "$(SRCROOT)/Sources/Supporting/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)";
PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.MessageKit;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -891,7 +890,6 @@
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
INFOPLIST_FILE = "$(SRCROOT)/Sources/Supporting/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)";
PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.MessageKit;
PRODUCT_NAME = "$(TARGET_NAME)";
diff --git a/README.md b/README.md
index 425ff0c9..5a4f0104 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
[](https://circleci.com/gh/MessageKit/MessageKit)
-[](https://codecov.io/gh/MessageKit/MessageKit)
+[](https://codecov.io/gh/MessageKit/MessageKit)
[](https://github.com/Carthage/Carthage)
diff --git a/Sources/Controllers/MessagesViewController+Keyboard.swift b/Sources/Controllers/MessagesViewController+Keyboard.swift
index 2abbd030..bb905d3e 100644
--- a/Sources/Controllers/MessagesViewController+Keyboard.swift
+++ b/Sources/Controllers/MessagesViewController+Keyboard.swift
@@ -32,7 +32,6 @@ internal extension MessagesViewController {
func addKeyboardObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(MessagesViewController.handleKeyboardDidChangeState(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(MessagesViewController.handleTextViewDidBeginEditing(_:)), name: UITextView.textDidBeginEditingNotification, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(MessagesViewController.adjustScrollViewTopInset), name: UIDevice.orientationDidChangeNotification, object: nil)
}
func removeKeyboardObservers() {
@@ -105,19 +104,6 @@ internal extension MessagesViewController {
// MARK: - Inset Computation
- @objc
- func adjustScrollViewTopInset() {
- if #available(iOS 11.0, *) {
- // No need to add to the top contentInset
- } else {
- let navigationBarInset = navigationController?.navigationBar.frame.height ?? 0
- let statusBarInset: CGFloat = UIApplication.shared.isStatusBarHidden ? 0 : 20
- let topInset = navigationBarInset + statusBarInset
- messagesCollectionView.contentInset.top = topInset
- messagesCollectionView.scrollIndicatorInsets.top = topInset
- }
- }
-
private func requiredScrollViewBottomInset(forKeyboardFrame keyboardFrame: CGRect) -> CGFloat {
// we only need to adjust for the part of the keyboard that covers (i.e. intersects) our collection view;
// see https://developer.apple.com/videos/play/wwdc2017/242/ for more details
@@ -137,16 +123,11 @@ internal extension MessagesViewController {
return max(0, inputAccessoryViewHeight + additionalBottomInset - automaticallyAddedBottomInset)
}
- /// iOS 11's UIScrollView can automatically add safe area insets to its contentInset,
+ /// UIScrollView can automatically add safe area insets to its contentInset,
/// which needs to be accounted for when setting the contentInset based on screen coordinates.
///
/// - Returns: The distance automatically added to contentInset.bottom, if any.
private var automaticallyAddedBottomInset: CGFloat {
- if #available(iOS 11.0, *) {
- return messagesCollectionView.adjustedContentInset.bottom - messagesCollectionView.contentInset.bottom
- } else {
- return 0
- }
+ return messagesCollectionView.adjustedContentInset.bottom - messagesCollectionView.contentInset.bottom
}
-
}
diff --git a/Sources/Controllers/MessagesViewController.swift b/Sources/Controllers/MessagesViewController.swift
index e74b0183..522997ed 100644
--- a/Sources/Controllers/MessagesViewController.swift
+++ b/Sources/Controllers/MessagesViewController.swift
@@ -130,13 +130,10 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
addKeyboardObservers()
messageCollectionViewBottomInset = requiredInitialScrollViewBottomInset()
}
- adjustScrollViewTopInset()
}
open override func viewSafeAreaInsetsDidChange() {
- if #available(iOS 11.0, *) {
- super.viewSafeAreaInsetsDidChange()
- }
+ super.viewSafeAreaInsetsDidChange()
messageCollectionViewBottomInset = requiredInitialScrollViewBottomInset()
}
@@ -153,8 +150,8 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
private func setupDefaults() {
extendedLayoutIncludesOpaqueBars = true
- automaticallyAdjustsScrollViewInsets = false
view.backgroundColor = .backgroundColor
+ messagesCollectionView.contentInsetAdjustmentBehavior = .never
messagesCollectionView.keyboardDismissMode = .interactive
messagesCollectionView.alwaysBounceVertical = true
messagesCollectionView.backgroundColor = .backgroundColor
@@ -172,17 +169,11 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
private func setupConstraints() {
messagesCollectionView.translatesAutoresizingMaskIntoConstraints = false
- let top = messagesCollectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: topLayoutGuide.length)
+ let top = messagesCollectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
let bottom = messagesCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
- if #available(iOS 11.0, *) {
- let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)
- let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)
- NSLayoutConstraint.activate([top, bottom, trailing, leading])
- } else {
- let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
- let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
- NSLayoutConstraint.activate([top, bottom, trailing, leading])
- }
+ let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)
+ let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)
+ NSLayoutConstraint.activate([top, bottom, trailing, leading])
}
// MARK: - Typing Indicator API
diff --git a/Sources/Models/AccessoryPosition.swift b/Sources/Models/AccessoryPosition.swift
index 04092026..cd2c486e 100644
--- a/Sources/Models/AccessoryPosition.swift
+++ b/Sources/Models/AccessoryPosition.swift
@@ -25,7 +25,7 @@
import Foundation
/// Used to determine the `Horizontal` and `Vertical` position of
-// an `AccessoryView` in a `MessageCollectionViewCell`.
+/// an `AccessoryView` in a `MessageCollectionViewCell`.
public enum AccessoryPosition {
/// Aligns the `AccessoryView`'s top edge to the cell's top edge.
diff --git a/Tests/ControllersTest/MessagesViewControllerSpec.swift b/Tests/ControllersTest/MessagesViewControllerSpec.swift
index 5717fb32..e33d4a76 100644
--- a/Tests/ControllersTest/MessagesViewControllerSpec.swift
+++ b/Tests/ControllersTest/MessagesViewControllerSpec.swift
@@ -63,9 +63,6 @@ final class MessagesViewControllerSpec: QuickSpec {
beforeEach {
controller.view.layoutIfNeeded()
}
- it("sets automaticallyAdjustsScrollViewInsets to false") {
- expect(controller.automaticallyAdjustsScrollViewInsets).to(beFalse())
- }
it("sets extendedLayoutIncludesOpaqueBars to true") {
expect(controller.extendedLayoutIncludesOpaqueBars).to(beTrue())
}