Merge branch 'development' into master
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 }}
|
||||
@@ -1 +0,0 @@
|
||||
5.0
|
||||
@@ -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
|
||||
- Sources
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
@@ -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)";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1130"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -40,8 +40,17 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
codeCoverageEnabled = "YES"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
codeCoverageEnabled = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "882B5E321CF7D4B900B6E160"
|
||||
BuildableName = "ChatExample.app"
|
||||
BlueprintName = "ChatExample"
|
||||
ReferencedContainer = "container:ChatExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -54,17 +63,6 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "882B5E321CF7D4B900B6E160"
|
||||
BuildableName = "ChatExample.app"
|
||||
BlueprintName = "ChatExample"
|
||||
ReferencedContainer = "container:ChatExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -86,8 +84,6 @@
|
||||
ReferencedContainer = "container:ChatExample.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1130"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -23,8 +23,6 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -36,8 +34,6 @@
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# 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 'cocoapods', '~> 1.9.1'
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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?()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 177 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 523 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 402 B |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 729 B After Width: | Height: | Size: 729 B |
|
Before Width: | Height: | Size: 969 B After Width: | Height: | Size: 969 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 661 B After Width: | Height: | Size: 661 B |
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "image_message_placeholder.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||