From 454b3f69dc86b2db980080123685c82f567e4385 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 13:00:22 +0100
Subject: [PATCH 01/56] Update changelog for development again
---
CHANGELOG.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 684b8da6..de8c4447 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
The changelog for `MessageKit`. Also see the [releases](https://github.com/MessageKit/MessageKit/releases) on GitHub.
+## Upcoming release
+
+### Fixed
+
+### Added
+
+### Changed
+
## 3.1.0
### Fixed
From fc9b0ce3865b3a3d44f640ca75cfd8717c6114f9 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 13:08:24 +0100
Subject: [PATCH 02/56] Change example build to use cache for pods, without
fetching specs
---
.circleci/config.yml | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 69c219d4..cc186781 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,7 +1,7 @@
# .circleci/config.yml
# Specify the config version - version 2 is latest.
-version: 2
+version: 2.1
# Define the jobs for the current project.
jobs:
@@ -16,7 +16,6 @@ jobs:
# Define the steps required to build the project.
steps:
-
# Get the code from the VCS provider.
- checkout
- run:
@@ -31,12 +30,25 @@ jobs:
- 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: Open Example
+ command: cd Example
+ - restore_cache:
+ name: Restore Pods cache
+ keys:
+ - v1-pods-cache-{{ arch }}-{{ checksum "Podfile.lock" }}
+ - v1-pods-cache-{{ arch }}-
+# - 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
+ command: pod install
+ - save_cache:
+ name: Save Pods cache
+ paths:
+ - Pods
+ key: v1-pods-cache-{{ arch }}-{{ checksum "Podfile.lock" }}
- 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
@@ -62,7 +74,6 @@ jobs:
# destination: scan-logs
workflows:
- version: 2
build-and-deploy:
jobs:
- build-and-test
From 426dbde283404158daf9b5a2cb988e1fe67d852d Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 13:18:16 +0100
Subject: [PATCH 03/56] Update pods cache
---
.circleci/config.yml | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index cc186781..edc4d896 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -30,25 +30,22 @@ jobs:
- run:
name: Build and run tests
command: xcodebuild test -project MessageKit.xcodeproj -scheme MessageKitTests -destination "$DESTINATION" CODE_SIGNING_REQUIRED=NO | xcpretty -c
- - run:
- name: Open Example
- command: cd Example
- restore_cache:
name: Restore Pods cache
keys:
- - v1-pods-cache-{{ arch }}-{{ checksum "Podfile.lock" }}
+ - v1-pods-cache-{{ arch }}-{{ checksum "Example/Podfile.lock" }}
- v1-pods-cache-{{ arch }}-
# - 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: pod install
+ command: cd Example && pod install
- save_cache:
name: Save Pods cache
paths:
- Pods
- key: v1-pods-cache-{{ arch }}-{{ checksum "Podfile.lock" }}
+ key: v1-pods-cache-{{ arch }}-{{ checksum "Example/Podfile.lock" }}
- 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
From 60e09a69c1134a3aa29ca8fdd09207fa5df8eeb6 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 13:31:22 +0100
Subject: [PATCH 04/56] Update config and podspec
---
.circleci/config.yml | 22 ++++++++--------------
MessageKit.podspec | 6 ------
2 files changed, 8 insertions(+), 20 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index edc4d896..78e7f1be 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,19 +1,13 @@
-# .circleci/config.yml
-
-# Specify the config version - version 2 is latest.
+# Specify the config version
version: 2.1
-# Define the jobs for the current project.
+# Define the jobs for the current project
jobs:
- build-and-test:
-
+ build_tests:
+ macos:
+ xcode: 11.3.1
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.
@@ -71,6 +65,6 @@ jobs:
# destination: scan-logs
workflows:
- build-and-deploy:
- jobs:
- - build-and-test
+ build_and_tests:
+ jobs:
+ - build_tests
diff --git a/MessageKit.podspec b/MessageKit.podspec
index f2b4abd5..cd49bca1 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.resource_bundle = { 'MessageKitAssets' => 'Assets/MessageKitAssets.bundle/Images' }
- s.requires_arc = true
-
s.dependency 'InputBarAccessoryView', '~> 4.3.0'
end
From 8567db0bdf861f1e910561c3e5318564258bd88a Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 13:32:04 +0100
Subject: [PATCH 05/56] Fix string char
---
.circleci/config.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 78e7f1be..a7fed834 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -34,7 +34,7 @@ jobs:
# command: curl -sS https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash
- run:
name: Update Pods
- command: cd Example && pod install
+ command: cd Example && pod install
- save_cache:
name: Save Pods cache
paths:
From 5fb307987efac2ce0df10d4ea72e4fbf6642a655 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 13:41:57 +0100
Subject: [PATCH 06/56] Pre-start simulator for running tests
---
.circleci/config.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index a7fed834..45e86174 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -15,6 +15,9 @@ jobs:
- run:
name: Update Homebrew
command: brew update
+ - run:
+ name: Pre-start simulator
+ command: xcrun instruments -w "iPhone 11 Pro (13.3) [" || true
- run:
name: Bootstrap Carthage
command: carthage bootstrap --platform ios
From 248e364fb27138854bd5d2669eb0a370563a8177 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 13:59:32 +0100
Subject: [PATCH 07/56] Fix config
---
.circleci/config.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 45e86174..708b81dc 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -15,12 +15,12 @@ jobs:
- run:
name: Update Homebrew
command: brew update
- - run:
- name: Pre-start simulator
- command: xcrun instruments -w "iPhone 11 Pro (13.3) [" || true
- run:
name: Bootstrap Carthage
command: carthage bootstrap --platform ios
+ - run:
+ name: Pre-start simulator
+ command: xcrun instruments -w "iPhone 11 Pro (13.3) [" || true
- run:
name: Build framework
command: xcodebuild build -project MessageKit.xcodeproj -scheme MessageKit -destination "$DESTINATION" CODE_SIGNING_REQUIRED=NO | xcpretty -c
From 97357c722847e117209bb493aff5ef5ce2806e4c Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 14:08:52 +0100
Subject: [PATCH 08/56] Add Github Actions config for Danger and Swiftlint
running on PRs
---
.github/workflows/danger.yml | 19 +++++++++++++++++++
Dangerfile | 28 ++++++++++++++++++++++++++++
Gemfile | 6 ++++++
3 files changed, 53 insertions(+)
create mode 100644 .github/workflows/danger.yml
create mode 100644 Dangerfile
create mode 100644 Gemfile
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
new file mode 100644
index 00000000..72404745
--- /dev/null
+++ b/.github/workflows/danger.yml
@@ -0,0 +1,19 @@
+name: PR Danger
+
+on: pull_request
+
+jobs:
+ danger:
+ name: Run Danger
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout the Git repository
+ uses: actions/checkout@v2
+ - name: Setup Ruby
+ uses: actions/setup-ruby@v1
+ with:
+ ruby-version: '2.6'
+ - name: Run build script
+ command: gem install bundler && bundle install && bundle exec danger --fail-on-errors=true
+ env:
+ DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/Dangerfile b/Dangerfile
new file mode 100644
index 00000000..7105cc7b
--- /dev/null
+++ b/Dangerfile
@@ -0,0 +1,28 @@
+# By Jakub Kaspar 26/02/2020
+# MessageKit, 2020
+
+# 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
+
+if !git.modified_files.include?("CHANGELOG.md") && has_app_changes
+ 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 PR - you should create smaller!")
+end
+
+swiftlint.config_file = '.swiftlint.yml'
+swiftlint.lint_files inline_mode:true
+swiftlint.lint_files fail_on_error:true
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 00000000..96db7633
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,6 @@
+# By Jakub Kaspar 26/02/2020
+# MessageKit, 2020
+
+source 'https://rubygems.org'
+gem 'danger', '~> 6.2'
+gem 'danger-swiftlint', '~> 0.24'
From b6ca5cf34a4854c376e31bd323fad716133044cb Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Wed, 26 Feb 2020 14:15:05 +0100
Subject: [PATCH 09/56] Fix syntax for run
---
.github/workflows/danger.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index 72404745..677dddd7 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -14,6 +14,6 @@ jobs:
with:
ruby-version: '2.6'
- name: Run build script
- command: gem install bundler && bundle install && bundle exec danger --fail-on-errors=true
+ run: gem install bundler && bundle install && bundle exec danger --fail-on-errors=true
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
From 12c23a87290d16c22f989e06a12b76e73561be0c Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 08:51:16 +0100
Subject: [PATCH 10/56] Fix PR
---
Dangerfile | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Dangerfile b/Dangerfile
index 7105cc7b..62cee39f 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -1,4 +1,3 @@
-# By Jakub Kaspar 26/02/2020
# MessageKit, 2020
# This runs on CI
@@ -14,13 +13,14 @@ if github.pr_body.length < 5
fail("Please provide a summary in the Pull Request description")
end
-if !git.modified_files.include?("CHANGELOG.md") && has_app_changes
+declared_hashtag = github.pr_title.include?("#trivial")
+if !git.modified_files.include?("CHANGELOG.md") && !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 PR - you should create smaller!")
+ warn("Big Pull Request - Please consider splitting up your changes into smaller Pull Requests.")
end
swiftlint.config_file = '.swiftlint.yml'
From 5ba964ba0f7df3259389def1fe6ef85c1c19ea1a Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 09:27:05 +0100
Subject: [PATCH 11/56] Update config
---
.circleci/config.yml | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 708b81dc..bec3ab99 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -19,6 +19,7 @@ jobs:
name: Bootstrap Carthage
command: carthage bootstrap --platform ios
- run:
+ # More info about pre-start of the simulator at https://circleci.com/docs/2.0/testing-ios/#pre-starting-the-simulator
name: Pre-start simulator
command: xcrun instruments -w "iPhone 11 Pro (13.3) [" || true
- run:
@@ -30,8 +31,8 @@ jobs:
- restore_cache:
name: Restore Pods cache
keys:
- - v1-pods-cache-{{ arch }}-{{ checksum "Example/Podfile.lock" }}
- - v1-pods-cache-{{ arch }}-
+ - v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
+ - v1-pods-cache-{{ arch }}-{{ .Branch }}-
# - run:
# name: Fetch CocoaPods Specs
# command: curl -sS https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash
@@ -42,7 +43,7 @@ jobs:
name: Save Pods cache
paths:
- Pods
- key: v1-pods-cache-{{ arch }}-{{ checksum "Example/Podfile.lock" }}
+ key: v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
- 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
@@ -68,6 +69,6 @@ jobs:
# destination: scan-logs
workflows:
- build_and_tests:
- jobs:
- - build_tests
+ build_and_tests:
+ jobs:
+ - build_tests
From 6f5e96e0e3c121652e8f4572bbd85dd2ea956f49 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 09:28:31 +0100
Subject: [PATCH 12/56] Fix PR header
---
Gemfile | 1 -
1 file changed, 1 deletion(-)
diff --git a/Gemfile b/Gemfile
index 96db7633..a98db9de 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,4 +1,3 @@
-# By Jakub Kaspar 26/02/2020
# MessageKit, 2020
source 'https://rubygems.org'
From 53cfda99c6d37cb8827b6277cdf550e53d9ed770 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 13:18:07 +0100
Subject: [PATCH 13/56] Fix Dangerfile
---
Dangerfile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Dangerfile b/Dangerfile
index 62cee39f..e8cb2911 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -14,7 +14,8 @@ if github.pr_body.length < 5
end
declared_hashtag = github.pr_title.include?("#trivial")
-if !git.modified_files.include?("CHANGELOG.md") && !declared_hashtag
+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
From eff62f8129fb83ea6e40aa60274ec883366b4d93 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 13:34:12 +0100
Subject: [PATCH 14/56] Remove deprecated file for swift version
---
.swift-version | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 .swift-version
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
From 7c66e23d9334c9e1cc6ab77071f8afdb0fc30c89 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 15:08:12 +0100
Subject: [PATCH 15/56] Update Copyright date
---
LICENSE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
From bc7ba72a52a4f109c783a87efb98c2bc5085b3fa Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 15:13:14 +0100
Subject: [PATCH 16/56] Drop iOS 9 and iOS 10
---
MessageKit.podspec | 4 ++--
MessageKit.xcodeproj/project.pbxproj | 6 ++----
.../MessagesViewController+Keyboard.swift | 20 +-----------------
.../Controllers/MessagesViewController.swift | 21 ++++++-------------
4 files changed, 11 insertions(+), 40 deletions(-)
diff --git a/MessageKit.podspec b/MessageKit.podspec
index cd49bca1..dfe3a5a0 100644
--- a/MessageKit.podspec
+++ b/MessageKit.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'MessageKit'
- s.version = '3.1.0-beta.1'
+ s.version = '3.1.0'
s.license = { :type => "MIT", :file => "LICENSE.md" }
s.summary = 'An elegant messages UI library for iOS.'
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
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.dependency 'InputBarAccessoryView', '~> 4.3.0'
diff --git a/MessageKit.xcodeproj/project.pbxproj b/MessageKit.xcodeproj/project.pbxproj
index 72509f16..f057f989 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/Sources/Controllers/MessagesViewController+Keyboard.swift b/Sources/Controllers/MessagesViewController+Keyboard.swift
index 2abbd030..223c3efe 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
@@ -142,11 +128,7 @@ internal extension MessagesViewController {
///
/// - 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
From 26c38d512a5e265be6d31c9f5ee70966bcf5e232 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 15:17:23 +0100
Subject: [PATCH 17/56] Update example project
---
Example/ChatExample.xcodeproj/project.pbxproj | 4 +--
.../xcschemes/ChatExample.xcscheme | 28 ++++++++-----------
.../xcschemes/ChatExampleUITests.xcscheme | 6 +---
Example/Podfile | 2 +-
Example/Podfile.lock | 8 +++---
.../LaunchViewController.swift | 8 ++----
.../NavigationController.swift | 12 ++------
.../MessagesViewController+Keyboard.swift | 2 +-
8 files changed, 26 insertions(+), 44 deletions(-)
diff --git a/Example/ChatExample.xcodeproj/project.pbxproj b/Example/ChatExample.xcodeproj/project.pbxproj
index 89a85340..e7a86915 100644
--- a/Example/ChatExample.xcodeproj/project.pbxproj
+++ b/Example/ChatExample.xcodeproj/project.pbxproj
@@ -647,7 +647,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 +699,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;
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 @@
-
-
-
-
-
-
-
-
-
-
-
-
4.3.0)
DEPENDENCIES:
@@ -18,8 +18,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
InputBarAccessoryView: 58a348be7ea2736c7eec60e5c315511c2dbb39fd
- MessageKit: 6b809a162328346e0727dbcd040b5f9fd5f5ba15
+ MessageKit: 3c593dc22f7465f74822e4a873ef3157a3e05080
-PODFILE CHECKSUM: 90bd12ca685503630d7fe716609f4974660ed5ee
+PODFILE CHECKSUM: 4b1c4ce3f56911e047bb185e2994398be7f67d2a
-COCOAPODS: 1.8.4
+COCOAPODS: 1.9.0
diff --git a/Example/Sources/View Controllers/LaunchViewController.swift b/Example/Sources/View Controllers/LaunchViewController.swift
index 50794115..d4b49550 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
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/Sources/Controllers/MessagesViewController+Keyboard.swift b/Sources/Controllers/MessagesViewController+Keyboard.swift
index 223c3efe..816a9ad1 100644
--- a/Sources/Controllers/MessagesViewController+Keyboard.swift
+++ b/Sources/Controllers/MessagesViewController+Keyboard.swift
@@ -123,7 +123,7 @@ 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.
From c57db5f4b2188b434b95f7c9afdeddc995953330 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 15:19:24 +0100
Subject: [PATCH 18/56] Update changelog
---
CHANGELOG.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de8c4447..98ec6126 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,8 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa
### 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
From e20dcc44925872531f8f8775aed23f9dda2419e7 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 15:25:19 +0100
Subject: [PATCH 19/56] Remove travis.ci file as this project uses Circle CI
---
.travis.yml | 53 -----------------------------------------------------
1 file changed, 53 deletions(-)
delete mode 100644 .travis.yml
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)
From 9a492e916a689b660668e051195da5d3d02ca4f3 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 15:39:28 +0100
Subject: [PATCH 20/56] Fix tests
---
Tests/ControllersTest/MessagesViewControllerSpec.swift | 3 ---
1 file changed, 3 deletions(-)
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())
}
From 46616a05e1beadd6c343890c2a3b68dbd94528fe Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 21:05:12 +0100
Subject: [PATCH 21/56] Update codecov code
---
.codecov.yml | 32 --------------------------------
codecov.yml | 16 ++++++++++++++++
2 files changed, 16 insertions(+), 32 deletions(-)
delete mode 100644 .codecov.yml
create mode 100644 codecov.yml
diff --git a/.codecov.yml b/.codecov.yml
deleted file mode 100644
index 18f175cb..00000000
--- a/.codecov.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-codecov:
- branch: develop
-
-coverage:
- precision: 2
- round: nearest
- range: "60...100"
- ignore:
- - Tests/*
-
-status:
- project:
- default:
- target: auto
- threshold: 2.0
- branches:
- - master
- - develop
-
- patch:
- default:
- target: auto
- branches:
- - master
- - develop
-
-comment:
- layout: "header, diff, changes, sunburst, uncovered"
- branches:
- - master
- - develop
- behavior: default
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 00000000..e816b1e2
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,16 @@
+codecov:
+ require_ci_to_pass: true
+
+coverage:
+ precision: 2
+ round: nearest
+ range: "40...100"
+ ignore:
+ - Tests/*
+
+comment:
+ layout: "header, diff, changes, sunburst, uncovered"
+ branches:
+ - master
+ - development
+ behavior: default
From b0ab6f99e36bc4d4be64e59ccd41a7648993c25a Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 28 Feb 2020 21:06:23 +0100
Subject: [PATCH 22/56] Fix badge for correct branch
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 75c8a413..ed2ea152 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)
From 1cc29a977db48325541fbcc9b0c74db4d96f02f3 Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Mon, 9 Mar 2020 17:54:13 +0100
Subject: [PATCH 23/56] feat: SwiftLint in Example project
---
Example/ChatExample.xcodeproj/project.pbxproj | 2 +-
Example/Gemfile | 25 ++++++
Example/Gemfile.lock | 90 +++++++++++++++++++
Example/Podfile | 14 +--
Example/Podfile.lock | 10 ++-
5 files changed, 130 insertions(+), 11 deletions(-)
create mode 100644 Example/Gemfile
create mode 100644 Example/Gemfile.lock
diff --git a/Example/ChatExample.xcodeproj/project.pbxproj b/Example/ChatExample.xcodeproj/project.pbxproj
index 89a85340..b205360d 100644
--- a/Example/ChatExample.xcodeproj/project.pbxproj
+++ b/Example/ChatExample.xcodeproj/project.pbxproj
@@ -523,7 +523,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 */
diff --git a/Example/Gemfile b/Example/Gemfile
new file mode 100644
index 00000000..c9cc8966
--- /dev/null
+++ b/Example/Gemfile
@@ -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'
\ No newline at end of file
diff --git a/Example/Gemfile.lock b/Example/Gemfile.lock
new file mode 100644
index 00000000..b616c2da
--- /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.0)
+ activesupport (>= 4.0.2, < 5)
+ claide (>= 1.0.2, < 2.0)
+ cocoapods-core (= 1.9.0)
+ 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.0)
+ 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)
+
+BUNDLED WITH
+ 2.1.4
diff --git a/Example/Podfile b/Example/Podfile
index 2e94b538..1d02871e 100644
--- a/Example/Podfile
+++ b/Example/Podfile
@@ -5,13 +5,13 @@ platform :ios, '9.0'
target 'ChatExample' do
use_frameworks!
pod 'MessageKit', :path => '../'
+ pod 'SwiftLint', '~> 0.39.1'
-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 d99a2460..90135709 100644
--- a/Example/Podfile.lock
+++ b/Example/Podfile.lock
@@ -4,13 +4,16 @@ PODS:
- InputBarAccessoryView/Core (4.3.1)
- MessageKit (3.1.0-beta.1):
- InputBarAccessoryView (~> 4.3.0)
+ - SwiftLint (0.39.1)
DEPENDENCIES:
- MessageKit (from `../`)
+ - SwiftLint (~> 0.39.1)
SPEC REPOS:
trunk:
- InputBarAccessoryView
+ - SwiftLint
EXTERNAL SOURCES:
MessageKit:
@@ -18,8 +21,9 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
InputBarAccessoryView: 58a348be7ea2736c7eec60e5c315511c2dbb39fd
- MessageKit: 6b809a162328346e0727dbcd040b5f9fd5f5ba15
+ MessageKit: 01a62c3f7de7b4055e44c28689f94d3df59005fb
+ SwiftLint: 55e96a4a4d537d4a3156859fc1c54bd24851a046
-PODFILE CHECKSUM: 90bd12ca685503630d7fe716609f4974660ed5ee
+PODFILE CHECKSUM: 71c5ec35ac2c10fb00dc79becd288bc472fdc6bf
-COCOAPODS: 1.8.4
+COCOAPODS: 1.9.0
From ce54a3ba7e2ca23e6eca21da43a5fe5541f27b11 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 02:07:50 +0100
Subject: [PATCH 24/56] Revert "Update codecov code"
This reverts commit 46616a05e1beadd6c343890c2a3b68dbd94528fe.
---
.codecov.yml | 32 ++++++++++++++++++++++++++++++++
codecov.yml | 16 ----------------
2 files changed, 32 insertions(+), 16 deletions(-)
create mode 100644 .codecov.yml
delete mode 100644 codecov.yml
diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644
index 00000000..18f175cb
--- /dev/null
+++ b/.codecov.yml
@@ -0,0 +1,32 @@
+codecov:
+ branch: develop
+
+coverage:
+ precision: 2
+ round: nearest
+ range: "60...100"
+ ignore:
+ - Tests/*
+
+status:
+ project:
+ default:
+ target: auto
+ threshold: 2.0
+ branches:
+ - master
+ - develop
+
+ patch:
+ default:
+ target: auto
+ branches:
+ - master
+ - develop
+
+comment:
+ layout: "header, diff, changes, sunburst, uncovered"
+ branches:
+ - master
+ - develop
+ behavior: default
diff --git a/codecov.yml b/codecov.yml
deleted file mode 100644
index e816b1e2..00000000
--- a/codecov.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-codecov:
- require_ci_to_pass: true
-
-coverage:
- precision: 2
- round: nearest
- range: "40...100"
- ignore:
- - Tests/*
-
-comment:
- layout: "header, diff, changes, sunburst, uncovered"
- branches:
- - master
- - development
- behavior: default
From 8d06c0c606ab198a9034bb35bb9ef0f2b521c489 Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Tue, 10 Mar 2020 08:28:15 +0100
Subject: [PATCH 25/56] feat: SwiftLint in Example project
circleci Bundle setup
---
.circleci/config.yml | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index bec3ab99..2cf3a77e 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -28,17 +28,23 @@ jobs:
- run:
name: Build and run tests
command: xcodebuild test -project MessageKit.xcodeproj -scheme MessageKitTests -destination "$DESTINATION" CODE_SIGNING_REQUIRED=NO | xcpretty -c
+ - restore_cache:
+ name: Restore bundle cache
+ key: 1-gems-{{ checksum "Example/Gemfile.lock" }}
+ - run:
+ name: Install bundle
+ command: cd Example && bundle check || bundle install
+ - save_cache:
+ name: Save bundle cache
+ key: 1-gems-{{ checksum "Example/Gemfile.lock" }}
- restore_cache:
name: Restore Pods cache
keys:
- v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
- v1-pods-cache-{{ arch }}-{{ .Branch }}-
-# - 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
+ command: bundle exec pod install
- save_cache:
name: Save Pods cache
paths:
@@ -48,14 +54,6 @@ jobs:
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.
From 27c42a49c17f6521d1558c67b67cd70df6414a9c Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Tue, 10 Mar 2020 08:56:56 +0100
Subject: [PATCH 26/56] feat: SwiftLint in Example project
circleci Bundle paths
---
.circleci/config.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 2cf3a77e..fe2dadb3 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -33,10 +33,12 @@ jobs:
key: 1-gems-{{ checksum "Example/Gemfile.lock" }}
- run:
name: Install bundle
- command: cd Example && bundle check || bundle install
+ command: cd Example && bundle check || bundle install --path vendor/bundle
- save_cache:
name: Save bundle cache
key: 1-gems-{{ checksum "Example/Gemfile.lock" }}
+ paths:
+ - vendor/bundle
- restore_cache:
name: Restore Pods cache
keys:
From 1fd1acabbe046363236083778f11088a703c5e88 Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Tue, 10 Mar 2020 09:16:46 +0100
Subject: [PATCH 27/56] feat: SwiftLint in Example project
---
Example/Gemfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Example/Gemfile b/Example/Gemfile
index c9cc8966..afe2a1ce 100644
--- a/Example/Gemfile
+++ b/Example/Gemfile
@@ -22,4 +22,4 @@
# SOFTWARE.
source 'https://rubygems.org'
-gem 'cocoapods', '~> 1.9'
\ No newline at end of file
+gem 'cocoapods', '~> 1.9'
From 01c80a9e38d95d55c99c4d28ac07993b88a0dbad Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Tue, 10 Mar 2020 09:28:43 +0100
Subject: [PATCH 28/56] feat: SwiftLint in Example project
circleci pod install with bundler fixed correct path
---
.circleci/config.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index fe2dadb3..7aaca346 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -46,7 +46,7 @@ jobs:
- v1-pods-cache-{{ arch }}-{{ .Branch }}-
- run:
name: Update Pods
- command: bundle exec pod install
+ command: cd Example && bundle exec pod install
- save_cache:
name: Save Pods cache
paths:
From dc17fb6d896d03996f39f696186880a144d92299 Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Tue, 10 Mar 2020 09:50:59 +0100
Subject: [PATCH 29/56] feat: SwiftLint in Example project
circleci bundle cache with args and branch identifiers
---
.circleci/config.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 7aaca346..4af61759 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -30,13 +30,13 @@ jobs:
command: xcodebuild test -project MessageKit.xcodeproj -scheme MessageKitTests -destination "$DESTINATION" CODE_SIGNING_REQUIRED=NO | xcpretty -c
- restore_cache:
name: Restore bundle cache
- key: 1-gems-{{ checksum "Example/Gemfile.lock" }}
+ key: 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
- run:
name: Install bundle
command: cd Example && bundle check || bundle install --path vendor/bundle
- save_cache:
name: Save bundle cache
- key: 1-gems-{{ checksum "Example/Gemfile.lock" }}
+ key: 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
paths:
- vendor/bundle
- restore_cache:
From 967cab03fcf87de5348b36f4359ecb8ae89f7795 Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Tue, 10 Mar 2020 10:03:39 +0100
Subject: [PATCH 30/56] feat: SwiftLint in Example project
circleci bundle cache with args and branch identifiers without lock
---
.circleci/config.yml | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 4af61759..eaefbcfd 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -30,27 +30,31 @@ jobs:
command: xcodebuild test -project MessageKit.xcodeproj -scheme MessageKitTests -destination "$DESTINATION" CODE_SIGNING_REQUIRED=NO | xcpretty -c
- restore_cache:
name: Restore bundle cache
- key: 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
+ keys:
+ - 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
+ - 1-gems-{{ arch }}-{{ .Branch }}-
- run:
name: Install bundle
command: cd Example && bundle check || bundle install --path vendor/bundle
- save_cache:
name: Save bundle cache
- key: 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
+ keys:
+ - 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
+ - 1-gems-{{ arch }}-{{ .Branch }}-
paths:
- vendor/bundle
- restore_cache:
name: Restore Pods cache
keys:
- - v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
- - v1-pods-cache-{{ arch }}-{{ .Branch }}-
+ - v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
+ - v1-pods-cache-{{ arch }}-{{ .Branch }}-
- run:
name: Update Pods
command: cd Example && bundle exec pod install
- save_cache:
name: Save Pods cache
paths:
- - Pods
+ - Pods
key: v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
- run:
name: Build and analyze Example
From eb241f3a7012047b890032161caee1303559084a Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Tue, 10 Mar 2020 10:06:24 +0100
Subject: [PATCH 31/56] feat: SwiftLint in Example project
circleci fix bundle save cache
---
.circleci/config.yml | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index eaefbcfd..ca1ed1a8 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -38,9 +38,7 @@ jobs:
command: cd Example && bundle check || bundle install --path vendor/bundle
- save_cache:
name: Save bundle cache
- keys:
- - 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
- - 1-gems-{{ arch }}-{{ .Branch }}-
+ key: 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
paths:
- vendor/bundle
- restore_cache:
From b3c8d658cbf413f6b53a102886668075295c2b25 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 13:09:18 +0100
Subject: [PATCH 32/56] Switch to Github Actions, Update Danger
---
.github/workflows/ci_pr_example.yml | 27 +++++++++++
.github/workflows/ci_pr_framework.yml | 20 ++++++++
.github/workflows/ci_pr_tests.yml | 20 ++++++++
.github/workflows/danger.yml | 7 +++
.swiftlint.yml | 2 +-
Dangerfile | 13 +++---
Gemfile | 8 ++--
Gemfile.lock | 66 +++++++++++++++++++++++++++
build.sh | 44 ++++++++++++++++++
9 files changed, 195 insertions(+), 12 deletions(-)
create mode 100644 .github/workflows/ci_pr_example.yml
create mode 100644 .github/workflows/ci_pr_framework.yml
create mode 100644 .github/workflows/ci_pr_tests.yml
create mode 100644 Gemfile.lock
create mode 100755 build.sh
diff --git a/.github/workflows/ci_pr_example.yml b/.github/workflows/ci_pr_example.yml
new file mode 100644
index 00000000..58bc28df
--- /dev/null
+++ b/.github/workflows/ci_pr_example.yml
@@ -0,0 +1,27 @@
+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: Pods
+ key: ${{ runner.os }}-pods-${{ hashFiles('**/Example/Podfile.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-pods-
+ - name: Cache SPM
+ uses: actions/cache@v1
+ with:
+ path: .build
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-gems-
+ - name: Build and run example project
+ run: ./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..e8817f85
--- /dev/null
+++ b/.github/workflows/ci_pr_framework.yml
@@ -0,0 +1,20 @@
+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 }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-carthage-
+ - name: Build framework
+ run: ./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..1e61f9c1
--- /dev/null
+++ b/.github/workflows/ci_pr_tests.yml
@@ -0,0 +1,20 @@
+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 }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-carthage-
+ - name: Build and run tests
+ run: ./build.sh tests
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index 677dddd7..c72466d8 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -13,6 +13,13 @@ jobs:
uses: actions/setup-ruby@v1
with:
ruby-version: '2.6'
+ - name: Cache Gems
+ uses: actions/cache@v1
+ with:
+ path: vendor/bundle
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-gems-
- name: Run build script
run: gem install bundler && bundle install && bundle exec danger --fail-on-errors=true
env:
diff --git a/.swiftlint.yml b/.swiftlint.yml
index 5ebf9e77..037ce5b0 100644
--- a/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -16,4 +16,4 @@ opt_in_rules:
explicit_acl: error
explicit_top_level_acl: error
included:
- - Sources
\ No newline at end of file
+ - Sources
diff --git a/Dangerfile b/Dangerfile
index e8cb2911..187c6239 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -1,29 +1,28 @@
-# MessageKit, 2020
+# MessageKit, 2020
# 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")
+ 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")
+ 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).")
+ 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.")
+ 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
-swiftlint.lint_files fail_on_error:true
+swiftlint.lint_files inline_mode:true, fail_on_error:true
diff --git a/Gemfile b/Gemfile
index a98db9de..75c378ae 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,5 @@
-# MessageKit, 2020
+# MessageKit, 2020
-source 'https://rubygems.org'
-gem 'danger', '~> 6.2'
-gem 'danger-swiftlint', '~> 0.24'
+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..71782c63
--- /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.1)
+ 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.16.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.6.1)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ danger (~> 6.2)
+ danger-swiftlint (~> 0.24)
+
+BUNDLED WITH
+ 2.1.4
diff --git a/build.sh b/build.sh
new file mode 100755
index 00000000..30354a2b
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# MessageKit, 2020
+
+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'."
From 9237c50ac742f069694befa619ba466acfcfda31 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 13:13:25 +0100
Subject: [PATCH 33/56] Disable Example app cache until
https://github.com/MessageKit/MessageKit/pull/1272 is merged
---
.github/workflows/ci_pr_example.yml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/ci_pr_example.yml b/.github/workflows/ci_pr_example.yml
index 58bc28df..190bd5ef 100644
--- a/.github/workflows/ci_pr_example.yml
+++ b/.github/workflows/ci_pr_example.yml
@@ -16,12 +16,12 @@ jobs:
key: ${{ runner.os }}-pods-${{ hashFiles('**/Example/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- - name: Cache SPM
- uses: actions/cache@v1
- with:
- path: .build
- key: ${{ runner.os }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
- restore-keys: |
- ${{ runner.os }}-gems-
+# - name: Cache SPM
+# uses: actions/cache@v1
+# with:
+# path: .build
+# key: ${{ runner.os }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
+# restore-keys: |
+# ${{ runner.os }}-gems-
- name: Build and run example project
run: ./build.sh example
From 8ab69e119a7a6b6f7cfc37106c74f1421a6ac5f2 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 13:18:29 +0100
Subject: [PATCH 34/56] Re-enable cache
---
.github/workflows/ci_pr_example.yml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/ci_pr_example.yml b/.github/workflows/ci_pr_example.yml
index 190bd5ef..58bc28df 100644
--- a/.github/workflows/ci_pr_example.yml
+++ b/.github/workflows/ci_pr_example.yml
@@ -16,12 +16,12 @@ jobs:
key: ${{ runner.os }}-pods-${{ hashFiles('**/Example/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
-# - name: Cache SPM
-# uses: actions/cache@v1
-# with:
-# path: .build
-# key: ${{ runner.os }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
-# restore-keys: |
-# ${{ runner.os }}-gems-
+ - name: Cache SPM
+ uses: actions/cache@v1
+ with:
+ path: .build
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-gems-
- name: Build and run example project
run: ./build.sh example
From d34226f38b6f088b3b004f77f590eef3e48f8c5b Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 19:58:13 +0100
Subject: [PATCH 35/56] Fix swiftlint
---
.swiftlint.yml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.swiftlint.yml b/.swiftlint.yml
index 037ce5b0..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
From 8d2001222db95c7f4b4bfdcf1022de248cd2107f Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 20:42:39 +0100
Subject: [PATCH 36/56] Switch to macOS for danger
---
.github/workflows/danger.yml | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index c72466d8..a12cdaf1 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -5,14 +5,14 @@ on: pull_request
jobs:
danger:
name: Run Danger
- runs-on: ubuntu-latest
+ runs-on: macOS-latest
steps:
- name: Checkout the Git repository
uses: actions/checkout@v2
- - name: Setup Ruby
- uses: actions/setup-ruby@v1
- with:
- ruby-version: '2.6'
+# - name: Setup Ruby
+# uses: actions/setup-ruby@v1
+# with:
+# ruby-version: '2.6'
- name: Cache Gems
uses: actions/cache@v1
with:
From cddbf106081879150352504552f9cf650510e81f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Ka=C5=A1par?=
Date: Tue, 10 Mar 2020 20:44:17 +0100
Subject: [PATCH 37/56] Update Dangerfile
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Martin Púčik
---
Dangerfile | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/Dangerfile b/Dangerfile
index 187c6239..3ef010fc 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -1,4 +1,25 @@
-# MessageKit, 2020
+#
+# 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"]
From 5af92cf40079c84c7251bf65b0eb49ad6fc0afbf Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 20:48:04 +0100
Subject: [PATCH 38/56] Move script to subfolder
---
.github/workflows/ci_pr_example.yml | 2 +-
.github/workflows/ci_pr_framework.yml | 2 +-
.github/workflows/ci_pr_tests.yml | 2 +-
Gemfile | 23 ++++++++++++++++++++++-
build.sh => GitHubActions/build.sh | 23 ++++++++++++++++++++++-
Sources/Models/AccessoryPosition.swift | 2 +-
6 files changed, 48 insertions(+), 6 deletions(-)
rename build.sh => GitHubActions/build.sh (55%)
diff --git a/.github/workflows/ci_pr_example.yml b/.github/workflows/ci_pr_example.yml
index 58bc28df..8ab262a5 100644
--- a/.github/workflows/ci_pr_example.yml
+++ b/.github/workflows/ci_pr_example.yml
@@ -24,4 +24,4 @@ jobs:
restore-keys: |
${{ runner.os }}-gems-
- name: Build and run example project
- run: ./build.sh example
+ run: ./GitHubActions/build.sh example
diff --git a/.github/workflows/ci_pr_framework.yml b/.github/workflows/ci_pr_framework.yml
index e8817f85..3093777a 100644
--- a/.github/workflows/ci_pr_framework.yml
+++ b/.github/workflows/ci_pr_framework.yml
@@ -17,4 +17,4 @@ jobs:
restore-keys: |
${{ runner.os }}-carthage-
- name: Build framework
- run: ./build.sh framework
+ run: ./GitHubActions/build.sh framework
diff --git a/.github/workflows/ci_pr_tests.yml b/.github/workflows/ci_pr_tests.yml
index 1e61f9c1..cf1a250f 100644
--- a/.github/workflows/ci_pr_tests.yml
+++ b/.github/workflows/ci_pr_tests.yml
@@ -17,4 +17,4 @@ jobs:
restore-keys: |
${{ runner.os }}-carthage-
- name: Build and run tests
- run: ./build.sh tests
+ run: ./GitHubActions/build.sh tests
diff --git a/Gemfile b/Gemfile
index 75c378ae..ce1c92bd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,4 +1,25 @@
-# MessageKit, 2020
+#
+# 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'
diff --git a/build.sh b/GitHubActions/build.sh
similarity index 55%
rename from build.sh
rename to GitHubActions/build.sh
index 30354a2b..3f998f9a 100755
--- a/build.sh
+++ b/GitHubActions/build.sh
@@ -1,6 +1,27 @@
#!/bin/bash
-# MessageKit, 2020
+#
+# 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 {
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.
From 2dfbf65b3448ad30830046e390a237b430e0aa7c Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 10 Mar 2020 20:53:08 +0100
Subject: [PATCH 39/56] Remove unused code
---
.github/workflows/danger.yml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index a12cdaf1..5dbb31fc 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -9,10 +9,6 @@ jobs:
steps:
- name: Checkout the Git repository
uses: actions/checkout@v2
-# - name: Setup Ruby
-# uses: actions/setup-ruby@v1
-# with:
-# ruby-version: '2.6'
- name: Cache Gems
uses: actions/cache@v1
with:
From 419e2e96d7604e4277b0537bb0400dc4f6c2b7a7 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 17 Mar 2020 23:22:01 +0100
Subject: [PATCH 40/56] Get rid of Circle CI and unused travis file
---
.circleci/config.yml | 76 --------------------------------------------
.travis.yml | 53 ------------------------------
2 files changed, 129 deletions(-)
delete mode 100644 .circleci/config.yml
delete mode 100644 .travis.yml
diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index ca1ed1a8..00000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,76 +0,0 @@
-# Specify the config version
-version: 2.1
-
-# Define the jobs for the current project
-jobs:
- build_tests:
- macos:
- xcode: 11.3.1
- environment:
- - DESTINATION: "platform=iOS Simulator,name=iPhone 11 Pro"
- # 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:
- # More info about pre-start of the simulator at https://circleci.com/docs/2.0/testing-ios/#pre-starting-the-simulator
- name: Pre-start simulator
- command: xcrun instruments -w "iPhone 11 Pro (13.3) [" || true
- - 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
- - restore_cache:
- name: Restore bundle cache
- keys:
- - 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
- - 1-gems-{{ arch }}-{{ .Branch }}-
- - run:
- name: Install bundle
- command: cd Example && bundle check || bundle install --path vendor/bundle
- - save_cache:
- name: Save bundle cache
- key: 1-gems-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Gemfile.lock" }}
- paths:
- - vendor/bundle
- - restore_cache:
- name: Restore Pods cache
- keys:
- - v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
- - v1-pods-cache-{{ arch }}-{{ .Branch }}-
- - run:
- name: Update Pods
- command: cd Example && bundle exec pod install
- - save_cache:
- name: Save Pods cache
- paths:
- - Pods
- key: v1-pods-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Example/Podfile.lock" }}
- - 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
-
- # 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:
- build_and_tests:
- jobs:
- - build_tests
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)
From 71d175913b284c9c08572ab348a6889917e907c6 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Tue, 17 Mar 2020 23:27:47 +0100
Subject: [PATCH 41/56] Update swiftlint
---
Gemfile.lock | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Gemfile.lock b/Gemfile.lock
index 71782c63..f8857468 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -24,7 +24,7 @@ GEM
no_proxy_fix
octokit (~> 4.7)
terminal-table (~> 1)
- danger-swiftlint (0.24.1)
+ danger-swiftlint (0.24.2)
danger
rake (> 10)
thor (~> 0.19)
@@ -40,7 +40,7 @@ GEM
multipart-post (2.1.1)
nap (1.1.0)
no_proxy_fix (0.1.2)
- octokit (4.16.0)
+ octokit (4.17.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
open4 (1.3.4)
@@ -53,7 +53,7 @@ GEM
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thor (0.20.3)
- unicode-display_width (1.6.1)
+ unicode-display_width (1.7.0)
PLATFORMS
ruby
From 42d32abf3a1fe2bf57602c87c9e23ffdedabf6b1 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Thu, 19 Mar 2020 20:02:22 +0100
Subject: [PATCH 42/56] Update project and example
---
Example/Sources/View Controllers/LaunchViewController.swift | 4 +---
Example/UITests/ChatExampleUITests.swift | 6 +-----
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/Example/Sources/View Controllers/LaunchViewController.swift b/Example/Sources/View Controllers/LaunchViewController.swift
index d4b49550..fc25609b 100644
--- a/Example/Sources/View Controllers/LaunchViewController.swift
+++ b/Example/Sources/View Controllers/LaunchViewController.swift
@@ -96,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/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.
From d3f722d81ebd7f0c32da908fdf94130be7d96be5 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Thu, 19 Mar 2020 20:16:27 +0100
Subject: [PATCH 43/56] fix cache
---
.github/workflows/ci_pr_example.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci_pr_example.yml b/.github/workflows/ci_pr_example.yml
index 8ab262a5..dbeb0922 100644
--- a/.github/workflows/ci_pr_example.yml
+++ b/.github/workflows/ci_pr_example.yml
@@ -12,7 +12,7 @@ jobs:
- name: Cache Pods
uses: actions/cache@v1
with:
- path: Pods
+ path: Example/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Example/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
From 176c6cdd288558851c4aa1be4b68ccfc393d7cdd Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Fri, 20 Mar 2020 13:56:20 +0100
Subject: [PATCH 44/56] documentation: Loading remote image messages in Example
project
---
Example/ChatExample.xcodeproj/project.pbxproj | 32 ++++++---
Example/Podfile | 1 +
Example/Podfile.lock | 27 ++++++-
.../Sources/Data Generation/SampleData.swift | 42 ++++++-----
.../Settings+UserDefaults.swift | 0
Example/Sources/Models/MockMessage.swift | 10 +++
Example/Sources/Models/MockSocket.swift | 8 +--
.../AppIcon.appiconset/30243544-1024.png | Bin
.../AppIcon.appiconset/30243544-20.png | Bin
.../AppIcon.appiconset/30243544-20@2x.png | Bin
.../AppIcon.appiconset/30243544-20@3x.png | Bin
.../AppIcon.appiconset/30243544-29.png | Bin
.../AppIcon.appiconset/30243544-29@2x.png | Bin
.../AppIcon.appiconset/30243544-29@3x.png | Bin
.../AppIcon.appiconset/30243544-40.png | Bin
.../AppIcon.appiconset/30243544-40@2x.png | Bin
.../AppIcon.appiconset/30243544-40@3x.png | Bin
.../AppIcon.appiconset/30243544-60@2x.png | Bin
.../AppIcon.appiconset/30243544-60@3x.png | Bin
.../AppIcon.appiconset/30243544-76.png | Bin
.../AppIcon.appiconset/30243544-76@2x.png | Bin
.../AppIcon.appiconset/30243544-83.5@2x.png | Bin
.../AppIcon.appiconset/Contents.json | 0
.../Assets.xcassets/Contents.json | 0
.../Dan-Leonard.imageset/Contents.json | 0
.../Dan-Leonard.imageset/NiceSelfi.jpg | Bin
.../Nathan-Tannar.imageset/Contents.json | 0
.../Nathan-Tannar.imageset/Nathan.jpg | Bin
.../Steve-Jobs.imageset/Contents.json | 0
.../Steve-Jobs.imageset/Steve-Jobs.jpeg | Bin
.../Steven-Deutsch.imageset/7445580.jpeg | Bin
.../Steven-Deutsch.imageset/Contents.json | 0
.../Tim-Cook.imageset/Contents.json | 0
.../Tim-Cook.imageset/Tim-Cook.jpeg | Bin
.../Wu-Zhong.imageset/5061845.png | Bin
.../Wu-Zhong.imageset/Contents.json | 0
.../ic_appstore.imageset/Contents.json | 0
.../icons8-apple_app_store_filled.png | Bin
.../ic_at.imageset/Contents.json | 0
.../ic_at.imageset/icons8-email.png | Bin
.../ic_camera.imageset/Contents.json | 0
.../ic_camera.imageset/icons8-camera.png | Bin
.../ic_hashtag.imageset/Contents.json | 0
.../ic_hashtag.imageset/icons8-hashtag.png | Bin
.../ic_info.imageset/Contents.json | 0
.../ic_info.imageset/icons8-info.png | Bin
.../ic_keyboard.imageset/Contents.json | 0
.../ic_keyboard.imageset/icons8-keyboard.png | Bin
.../ic_library.imageset/Contents.json | 0
.../icons8-medium_icons.png | Bin
.../ic_like.imageset/Contents.json | 0
.../ic_like.imageset/icons8-like_it.png | Bin
.../ic_map_marker.imageset/Contents.json | 0
.../icons8-map_pin-1.png | Bin
.../ic_mic.imageset/Contents.json | 0
.../ic_mic.imageset/icons8-microphone.png | Bin
.../ic_send.imageset/Contents.json | 0
.../ic_send.imageset/icons8-sent.png | Bin
.../ic_typing.imageset/Contents.json | 0
.../icons8-hand_with_pen.png | Bin
.../ic_up.imageset/Contents.json | 0
.../ic_up.imageset/icons8-up_arrow.png | Bin
.../Contents.json | 12 ++++
.../image_message_placeholder.pdf | Bin 0 -> 5232 bytes
.../img1.imageset/Contents.json | 0
...crowned-crane-bird-crane-animal-45853.jpeg | Bin
.../img2.imageset/Contents.json | 0
.../img2.imageset/pexels-photo-145939.jpeg | Bin
.../mklogo.imageset/Contents.json | 0
.../mklogo.imageset/mklogo.png | Bin
.../mkorglogo.imageset/30243544.png | Bin
.../mkorglogo.imageset/Contents.json | 0
.../pin.imageset/Contents.json | 0
.../Assets.xcassets/pin.imageset/pin.png | Bin
.../Assets.xcassets/pin.imageset/pin@2x.png | Bin
.../Assets.xcassets/pin.imageset/pin@3x.png | Bin
.../Base.lproj/LaunchScreen.storyboard | 0
Example/Sources/{ => Resources}/Info.plist | 0
.../AdvancedExampleViewController.swift | 9 +++
.../AutocompleteExampleViewController.swift | 9 +++
.../BasicExampleViewController.swift | 9 +++
.../View Controllers/ChatViewController.swift | 66 +++++++++---------
.../SettingsViewController.swift | 2 +-
.../MessagesViewController+Keyboard.swift | 1 -
84 files changed, 155 insertions(+), 73 deletions(-)
rename Example/Sources/{ => Extensions}/Settings+UserDefaults.swift (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-1024.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-20.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-29.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-40.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-76.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/AppIcon.appiconset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Dan-Leonard.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Nathan-Tannar.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Steve-Jobs.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Steven-Deutsch.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Tim-Cook.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Wu-Zhong.imageset/5061845.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/Wu-Zhong.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_appstore.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_at.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_at.imageset/icons8-email.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_camera.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_camera.imageset/icons8-camera.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_hashtag.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_info.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_info.imageset/icons8-info.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_keyboard.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_library.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_like.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_like.imageset/icons8-like_it.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_map_marker.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_mic.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_mic.imageset/icons8-microphone.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_send.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_send.imageset/icons8-sent.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_typing.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_up.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png (100%)
create mode 100644 Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/Contents.json
create mode 100644 Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/image_message_placeholder.pdf
rename Example/Sources/{ => Resources}/Assets.xcassets/img1.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/img2.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/mklogo.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/mklogo.imageset/mklogo.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/mkorglogo.imageset/30243544.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/mkorglogo.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/pin.imageset/Contents.json (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/pin.imageset/pin.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/pin.imageset/pin@2x.png (100%)
rename Example/Sources/{ => Resources}/Assets.xcassets/pin.imageset/pin@3x.png (100%)
rename Example/Sources/{ => Resources}/Base.lproj/LaunchScreen.storyboard (100%)
rename Example/Sources/{ => Resources}/Info.plist (100%)
diff --git a/Example/ChatExample.xcodeproj/project.pbxproj b/Example/ChatExample.xcodeproj/project.pbxproj
index dacdddf3..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;
@@ -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/Podfile b/Example/Podfile
index de4002d1..b8a13964 100644
--- a/Example/Podfile
+++ b/Example/Podfile
@@ -6,6 +6,7 @@ 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
diff --git a/Example/Podfile.lock b/Example/Podfile.lock
index 1559e4fe..0b1fa87a 100644
--- a/Example/Podfile.lock
+++ b/Example/Podfile.lock
@@ -4,15 +4,35 @@ 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:
@@ -22,8 +42,11 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
InputBarAccessoryView: 7985d418040a05fe894bd4b8328dd43ab35517c3
MessageKit: 3c593dc22f7465f74822e4a873ef3157a3e05080
+ PINCache: 534fd41d358d828dfdf227a0d327f3673a65e20b
+ PINOperation: 24b774353ca248fcf87d67b2d61eef42087c125a
+ PINRemoteImage: e2b89e19fb6e77ffc099f9d9f3b3fe1745e3f9f9
SwiftLint: 55e96a4a4d537d4a3156859fc1c54bd24851a046
-PODFILE CHECKSUM: 3d2d8513a2319438f3480a9f1397e1f78b0a5021
+PODFILE CHECKSUM: cf0af8a506e2b58d4d51b99e165b58c56c26d619
-COCOAPODS: 1.9.1
+COCOAPODS: 1.9.0
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 0000000000000000000000000000000000000000..69de86ee31789bc210e2e80313c120ab645fdd51
GIT binary patch
literal 5232
zcmcgwc{r5a`?riRN{Wb7PhNu-W;H0gv9*n*vV>`d!Pv$!)*AbgElXr6yGXJWMPwIA
zuO&$;giv;ptoc17ec#@<@9%oA>-Wd+xn`bouKV2QKKK1O_c_lwAD9kKLlP;4hQb<0
z=0_%Szod6GHbF4}0-%y?pz`tn{509Yie?Q+gCacuu0gS*k)6TPjz}Zp$mUcFGN7mk
zb)h+viS|$rX8SWL+$@K9D!+tPD{oW7wRz1wx+TBQKL+xi&23{QVxqG&$t^a=p2Ir5
zfm3h=wSDMAyQkH&H#H78o@+OBY79(v<>EqhXX{;x)?u(N-f0gtd|q?uy?0sZR;iDk
z)L)vjBHrsLvw7t@8aB(!@kP`UN_Mc=8Xc@LoMw2+D3M5MMkAw&`X!!oo{nSyu0yoi
zd^?jJXaM?0YKtnWxPCj$&%)m)H(%umB`Lp;fbY);#3(Y8kdvRf^`
zjLH!G9Cd3}QA-dQCNW_nkRVg$VuvLv}??`n3b)mBV
zo+DEoeoWxgkiM)>7-S04A=dgbvu@kI7jfzTwNiTmVaLS8{Cfg1KxN>J#9)3-_-45O
zz#fVGzk~l5)KEB%>_#ysYdRA>!DRVsQh*OqfEK>ds58Xl6zu@yQs%WFs9j+70O1Ozmyou1Q@;-
z9iu;%`5L0S8*BmMjLWrKD;@ZqqNjJqt<0kH`Hg*LwG0UEOMK|wjewMa@)T!%>ecr`hP!{y5%0x#t6@;0^tYI4iHQ#adTv}2x_=I2>xB(W2H;7%3;3hWS_u2~DUomfbUJs7t9M7w*o;;l
zZ?0teIMjQwE_3{OVwvxeqe}~Qne)%JB-87miuj%b?B0*h*QM2TrA^8RKg^}jyt%x*
zmE2lPBa#ctm)6|dW<2Oh%R|+tXDj>;5UTYGN`|;^MzjTfYq-0|^MUot>$7v$j#sWX
z6{)1HD)e0LDM*K~`?G@iQ>!#xyN|@()$#k9+gwbH1%{RRsO9b=%(B@Q_=3^;vM!
zhO02XMGoKw25c=NJxy@q{kKn4$_@8(`n~)i?Nu^W9lJ#U*n*H3C-Cxw)*gs%sJ5>T
zOK_l=8;(tbZ`a`q7Uyc2HA6(q)%myr{7F5W^E^6Db-Fn9k-i99&Y1$~Fa62u%|-*g
zV`V+PRx|XT3MQR3e@H#ekl7cLVaPWhveW2D2g{877Ia4^~-M*vVDr
zw3C@ezDaa-E!{fJgy2geyciS9unR@0^9fFe&a*Ia#5Kx2apn$Rma|S}^2o9J7zPQ|
zCgtqvNu-Q?dSGo>~0pB9(4RvOik$sYN%v6E!)RfWd
zQS0TJ-hl(&`s)hMyjIW8iA}brszjt34cJZIgIDo0Es7f7++R{1f1at-ew*^h;63~d
zz%KE&K*{e9
z?LBC+`bbW0&MDlB7u&fL+AY?<@oWs&%2EDoX*hN(tyW+z=+k-KPjQ@qq1Kf_@_vTV
zQWnrapYB1Qy;yN}LGKh>K5JJ36Fo>yr(B!;8C8Kv?GIK_2PH2S`ou*ZB=lMJ6YGMQ
zB9|zX*Y~lNgIp$I4uhvvMD#}&w?|nx!!nNvW(@?|)v@f3W~Ze?F@91AmSdN82>YTP
zS^EK|Kwm8$)*Gx+S}YW0$O9F{H%w3!S)M(aDtDv#vv($`zUJ9y%;Bk~q9e=4`cy46nkQCyxkK#E-Xj5b
zGt_hx7XF|KRdARFtfaGd0GMs-%=Exri7Z{j9dDQ(`Suo{5a!UVZ~cJt*mH|rp!VJ1
z$#Q;0?y`D;!F{t#$ASp;*Ey7*ajL9aiZbsyWE&%r&61~{9L=4*?{TD7
zjMGQfZ6O)N#J&7Yg2N$35rd=)#Mh*gi0(x5#0#edMzNMWXuoCu+obOMIfml*l-xM6
zyKY8GHeR?Cb?IVp!hO~^#K{xF+|9LuL&A>U<$Fy~4$_5?vYkBLcuPU?A#XQ;m2ur!mCVf9IhafT*45IUXU7F^=`XUG*4UzdLxE
zNHC9QqY3Ho{cCSjo@fh;oxRSd9V{xKCwe%k)bE_Ojfkn3f>_m|>n+DEG@bVvDVyO7
zMbiKRY-g;JPMm}oAO57Ux@zxPxs#8TJ(WGxZtLy1F}?~%KS_scUPmW<
zNf>S^xSk(l8$Xe78HSJRNpMdfNTrDr4*8t?p0ifYqFbk2r|*|ld?7<)u(VzwNLxKQ
zGoEynluQaG1q?|))rCEY^@}arjn7m5T>KJt`;d@o*KN<2<)vpzkH00qMeNs<$zJWc
z{`u*`!B15SoMagJ;)ukE@QBbz$#cDJ^@vMLXg$H(5!WLsBci@wMjy8ix4**{QOq`;
z9FAW;;&9|jyhyxdJac^1-P7l(-F)3CckS=uUmM
z$F-30;)+nO@)et}4dV*q*M*XWs)YoF&I=`AnxqAj9gw3evJ`G;1#UJg@Bl-d+kpnOn&E)EaR*bO|s^X
zoWkZ5hcAj1ho)%9YDc!5(SP%*|JX@iDL(i4jZu<+Lw+OuQa@EOtv*Or#A=N44ap<<@Aj{
zEXb1_aI2Z3pGY<>?&GgKTiL$Iy(qFOwu)p|2=NH1;{NuA<|a`YNblY?@oBKUZ7yP%
zUHr26{Vwg?ffS>*!)-g-vbeSj%nH1c-0R%wG*~X|93y2R6+!TD%y@PFUHq`|#L9~^
zJ&|K>jrNUwZxnjh%U6%?Jhd}MGrT!2_xhMnJD1tjgd&3&gQBw7Z=@NUnOw!=ilK^;
zioDfs)%kSz5^BFt+7%o>eCJfDu=T&4Yd`
zO>)|E-50w?7d|F`bZFh*@}*_fTiR0E-PNkv?R)TAo%FOVcR|qWLX&ro&$^q|RSbTu
zo`|vs?6rDlTQyoE$@>Nz!unt7rt210U$QQl8EsO1tg1U$CE0e7+wQ5|9=oYN%aQ_{
zcL^e9onJ|a^H)^z^SU+i?>(ZKe%zYzwi58@x?HSWMtOcQTV~M
zVC2Po=6qSD!DRIX;zg%RJ1J2XQKhIm52{WU*=Tm>j%Sbi2}LE3R*hdSn@V}x{H~{F
zz}}~eIg<4$yW#;p;U_-NzUkN&sMtRxz8}2T&_0nlUQuJ^L-4^(Y0bs7YX)iFZmy4V
z?LP6UN9K-99JW3(w(0(`Q!{n_!&kM-y!oGX&{>a{AhL(#=7yS=4$h=*m+$oqqu>23
zzMi)DsKYqSIOFyE*P)NHv6RcFFAse7?Mm6-wqH`|=EjwUh{dGjlIK>Z+GE=G+`1{3
z=I%YO+7vVw9x4!W+<>N7QTp*^N?~zff2&_Yk=fj1=e&1St83>I@~sNxOi$2L=v7m}
z>yfVyRHoh_OnOs3Kb*0z`s`S;eq*@cS~VMeY{hgH-oIEuAGx-XvX3=<+sd?5_2mt-
z_X?ls{p+3Vc{|ONUU4rhu(@kdhcDiy4EFZEdFRV_@W_grc(xoQ;^T&@P+
zh+i(kH?XzmwI9_e)fm?-&}@%bj_C8czwmUnH6o#FIH>0E_ebC2JM+`L-B+uuNG*-C
zww)76N+Zu562F9xPm5G?zrwjT
z?;&PyIXdty@XP9dIj%B}p^W1y3X4Sjyd*L%%?ugH1Zbyn!PD_$i8o3rI3B&cvX-UuXg3uWZc^
zn`%TF(T-~MgXVDg$!}aBJG)S*4gee}h55DrmfH-MKr+L^)f^;vB?wMp%1 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/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/Sources/Controllers/MessagesViewController+Keyboard.swift b/Sources/Controllers/MessagesViewController+Keyboard.swift
index 816a9ad1..bb905d3e 100644
--- a/Sources/Controllers/MessagesViewController+Keyboard.swift
+++ b/Sources/Controllers/MessagesViewController+Keyboard.swift
@@ -130,5 +130,4 @@ internal extension MessagesViewController {
private var automaticallyAddedBottomInset: CGFloat {
return messagesCollectionView.adjustedContentInset.bottom - messagesCollectionView.contentInset.bottom
}
-
}
From 81d4387d9426df586f5698d24075271a37b03a4d Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Fri, 20 Mar 2020 14:02:16 +0100
Subject: [PATCH 45/56] build: Bump Cocoapods bundle version
---
Example/Gemfile | 2 +-
Example/Gemfile.lock | 8 ++++----
Example/Podfile.lock | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Example/Gemfile b/Example/Gemfile
index afe2a1ce..615a3f8e 100644
--- a/Example/Gemfile
+++ b/Example/Gemfile
@@ -22,4 +22,4 @@
# SOFTWARE.
source 'https://rubygems.org'
-gem 'cocoapods', '~> 1.9'
+gem 'cocoapods', '~> 1.9.1'
diff --git a/Example/Gemfile.lock b/Example/Gemfile.lock
index b616c2da..e8faf161 100644
--- a/Example/Gemfile.lock
+++ b/Example/Gemfile.lock
@@ -12,10 +12,10 @@ GEM
json (>= 1.5.1)
atomos (0.1.3)
claide (1.0.3)
- cocoapods (1.9.0)
+ cocoapods (1.9.1)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
- cocoapods-core (= 1.9.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)
@@ -31,7 +31,7 @@ GEM
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.14.0, < 2.0)
- cocoapods-core (1.9.0)
+ cocoapods-core (1.9.1)
activesupport (>= 4.0.2, < 6)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
@@ -84,7 +84,7 @@ PLATFORMS
ruby
DEPENDENCIES
- cocoapods (~> 1.9)
+ cocoapods (~> 1.9.1)
BUNDLED WITH
2.1.4
diff --git a/Example/Podfile.lock b/Example/Podfile.lock
index 0b1fa87a..9a7af340 100644
--- a/Example/Podfile.lock
+++ b/Example/Podfile.lock
@@ -49,4 +49,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: cf0af8a506e2b58d4d51b99e165b58c56c26d619
-COCOAPODS: 1.9.0
+COCOAPODS: 1.9.1
From f28e72a0850148b0829cc35aed754d1a6d5ed09f Mon Sep 17 00:00:00 2001
From: martinpucik
Date: Fri, 20 Mar 2020 14:17:07 +0100
Subject: [PATCH 46/56] Changelog
---
CHANGELOG.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04674e4f..806c3249 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa
### 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)
From 94a263d9889003314c11e6dea86f254cff85be61 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Fri, 20 Mar 2020 14:22:45 +0100
Subject: [PATCH 47/56] Update cache strategy with keys
---
.github/workflows/ci_pr_example.yml | 16 ++++++++++------
.github/workflows/ci_pr_framework.yml | 6 ++++--
.github/workflows/ci_pr_tests.yml | 6 ++++--
.github/workflows/danger.yml | 6 ++++--
4 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/ci_pr_example.yml b/.github/workflows/ci_pr_example.yml
index dbeb0922..cf543790 100644
--- a/.github/workflows/ci_pr_example.yml
+++ b/.github/workflows/ci_pr_example.yml
@@ -13,15 +13,19 @@ jobs:
uses: actions/cache@v1
with:
path: Example/Pods
- key: ${{ runner.os }}-pods-${{ hashFiles('**/Example/Podfile.lock') }}
+ key: ${{ runner.os }}-example-${{ env.cache-name }}-pods-${{ hashFiles('**/Example/Podfile.lock') }}
restore-keys: |
- ${{ runner.os }}-pods-
- - name: Cache SPM
+ ${{ 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: .build
- key: ${{ runner.os }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
+ path: vendor/bundle
+ key: ${{ runner.os }}-example-${{ env.cache-name }}-gems-${{ hashFiles('**/Example/Gemfile.lock') }}
restore-keys: |
- ${{ runner.os }}-gems-
+ ${{ 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
index 3093777a..2d17fbbc 100644
--- a/.github/workflows/ci_pr_framework.yml
+++ b/.github/workflows/ci_pr_framework.yml
@@ -13,8 +13,10 @@ jobs:
uses: actions/cache@v1
with:
path: Carthage
- key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
+ key: ${{ runner.os }}-framework-${{ env.cache-name }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
restore-keys: |
- ${{ runner.os }}-carthage-
+ ${{ 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
index cf1a250f..65cc396d 100644
--- a/.github/workflows/ci_pr_tests.yml
+++ b/.github/workflows/ci_pr_tests.yml
@@ -13,8 +13,10 @@ jobs:
uses: actions/cache@v1
with:
path: Carthage
- key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
+ key: ${{ runner.os }}-tests-${{ env.cache-name }}-carthage-${{ hashFiles('**/Cartfile.resolved') }}
restore-keys: |
- ${{ runner.os }}-carthage-
+ ${{ 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
index 5dbb31fc..5e149e68 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -13,9 +13,11 @@ jobs:
uses: actions/cache@v1
with:
path: vendor/bundle
- key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
+ key: ${{ runner.os }}-danger-${{ env.cache-name }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
- ${{ runner.os }}-gems-
+ ${{ 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:
From bd193d9f7f56ddf81c3c0b39893dd9b199fa85cf Mon Sep 17 00:00:00 2001
From: Travis Chapman
Date: Tue, 31 Mar 2020 18:30:58 -0600
Subject: [PATCH 48/56] fix spelling typo and rename UIImage extension filename
---
MessageKit.xcodeproj/project.pbxproj | 8 ++++----
Sources/Extensions/UIColor+Extensions.swift | 3 ---
...tension.swift => UIImage+Extensions.swift} | 10 ++++------
Sources/Views/Cells/ContactMessageCell.swift | 20 +++++++++----------
4 files changed, 18 insertions(+), 23 deletions(-)
rename Sources/Extensions/{UIImage+Extension.swift => UIImage+Extensions.swift} (96%)
diff --git a/MessageKit.xcodeproj/project.pbxproj b/MessageKit.xcodeproj/project.pbxproj
index 72509f16..813fa33d 100644
--- a/MessageKit.xcodeproj/project.pbxproj
+++ b/MessageKit.xcodeproj/project.pbxproj
@@ -50,7 +50,7 @@
5073C11D2175BEC60040EAD5 /* AudioMessageSizeCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5073C11C2175BEC60040EAD5 /* AudioMessageSizeCalculator.swift */; };
5073C1232175C1980040EAD5 /* sound1.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 5073C1222175C1980040EAD5 /* sound1.m4a */; };
50FF34552237FE4C0004DCD7 /* ContactItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FF34542237FE4C0004DCD7 /* ContactItem.swift */; };
- 50FF34572237FE6A0004DCD7 /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FF34562237FE6A0004DCD7 /* UIImage+Extension.swift */; };
+ 50FF34572237FE6A0004DCD7 /* UIImage+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FF34562237FE6A0004DCD7 /* UIImage+Extensions.swift */; };
50FF34592237FE850004DCD7 /* ContactMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FF34582237FE840004DCD7 /* ContactMessageCell.swift */; };
50FF345B2237FE9C0004DCD7 /* ContactMessageSizeCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50FF345A2237FE9C0004DCD7 /* ContactMessageSizeCalculator.swift */; };
88916B2D1CF0DF2F00469F91 /* MessageKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88916B221CF0DF2F00469F91 /* MessageKit.framework */; };
@@ -163,7 +163,7 @@
5073C11C2175BEC60040EAD5 /* AudioMessageSizeCalculator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AudioMessageSizeCalculator.swift; sourceTree = ""; };
5073C1222175C1980040EAD5 /* sound1.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = sound1.m4a; sourceTree = ""; };
50FF34542237FE4C0004DCD7 /* ContactItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactItem.swift; sourceTree = ""; };
- 50FF34562237FE6A0004DCD7 /* UIImage+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = ""; };
+ 50FF34562237FE6A0004DCD7 /* UIImage+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Extensions.swift"; sourceTree = ""; };
50FF34582237FE840004DCD7 /* ContactMessageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactMessageCell.swift; sourceTree = ""; };
50FF345A2237FE9C0004DCD7 /* ContactMessageSizeCalculator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactMessageSizeCalculator.swift; sourceTree = ""; };
88916B221CF0DF2F00469F91 /* MessageKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MessageKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -399,7 +399,7 @@
B09643981F295D43004D0129 /* Extensions */ = {
isa = PBXGroup;
children = (
- 50FF34562237FE6A0004DCD7 /* UIImage+Extension.swift */,
+ 50FF34562237FE6A0004DCD7 /* UIImage+Extensions.swift */,
0EE91E651FDEC887005420A2 /* CGRect+Extensions.swift */,
B7A03F671F8669EB006AEF79 /* Bundle+Extensions.swift */,
B7A03F681F8669EB006AEF79 /* NSAttributedString+Extensions.swift */,
@@ -695,7 +695,7 @@
1F6C040C206A2891007BDE44 /* MessageContentCell.swift in Sources */,
B7A03F2C1F866895006AEF79 /* DetectorType.swift in Sources */,
B7A03F271F866895006AEF79 /* Avatar.swift in Sources */,
- 50FF34572237FE6A0004DCD7 /* UIImage+Extension.swift in Sources */,
+ 50FF34572237FE6A0004DCD7 /* UIImage+Extensions.swift in Sources */,
1F82D1431FB1B75B00B81A88 /* AvatarPosition.swift in Sources */,
1FF377AC20087DA2004FD648 /* MessagesViewController+Keyboard.swift in Sources */,
);
diff --git a/Sources/Extensions/UIColor+Extensions.swift b/Sources/Extensions/UIColor+Extensions.swift
index 57f74578..0f73d460 100644
--- a/Sources/Extensions/UIColor+Extensions.swift
+++ b/Sources/Extensions/UIColor+Extensions.swift
@@ -65,9 +65,6 @@ internal extension UIColor {
return UIColor(red: 15/255, green: 135/255, blue: 255/255, alpha: 1.0)
}
}
-}
-
-internal extension UIColor {
static var backgroundColor: UIColor {
if #available(iOS 13, *) {
diff --git a/Sources/Extensions/UIImage+Extension.swift b/Sources/Extensions/UIImage+Extensions.swift
similarity index 96%
rename from Sources/Extensions/UIImage+Extension.swift
rename to Sources/Extensions/UIImage+Extensions.swift
index 5195a1e7..599c8fab 100644
--- a/Sources/Extensions/UIImage+Extension.swift
+++ b/Sources/Extensions/UIImage+Extensions.swift
@@ -22,22 +22,20 @@
SOFTWARE.
*/
+import UIKit
+
public enum ImageType: String {
case play
case pause
- case disclouser
+ case disclosure
}
-import UIKit
-
/// This extension provide a way to access image resources with in framework
-public extension UIImage {
-
+internal extension UIImage {
class func messageKitImageWith(type: ImageType) -> UIImage? {
let assetBundle = Bundle.messageKitAssetBundle()
let imagePath = assetBundle.path(forResource: type.rawValue, ofType: "png", inDirectory: "Images")
let image = UIImage(contentsOfFile: imagePath ?? "")
return image
}
-
}
diff --git a/Sources/Views/Cells/ContactMessageCell.swift b/Sources/Views/Cells/ContactMessageCell.swift
index 2273a834..5f19e957 100644
--- a/Sources/Views/Cells/ContactMessageCell.swift
+++ b/Sources/Views/Cells/ContactMessageCell.swift
@@ -28,7 +28,7 @@ open class ContactMessageCell: MessageContentCell {
public enum ConstraintsID: String {
case initialsContainerLeftConstraint
- case disclouserRigtConstraint
+ case disclosureRigtConstraint
}
/// The view container that holds contact initials
@@ -54,11 +54,11 @@ open class ContactMessageCell: MessageContentCell {
return nameLabel
}()
- /// The disclouser image view
+ /// The disclosure image view
public lazy var disclosureImageView: UIImageView = {
- let disclouserImage = UIImage.messageKitImageWith(type: .disclouser)?.withRenderingMode(.alwaysTemplate)
- let disclouser = UIImageView(image: disclouserImage)
- return disclouser
+ let disclosureImage = UIImage.messageKitImageWith(type: .disclosure)?.withRenderingMode(.alwaysTemplate)
+ let disclosure = UIImageView(image: disclosureImage)
+ return disclosure
}()
// MARK: - Methods
@@ -95,7 +95,7 @@ open class ContactMessageCell: MessageContentCell {
disclosureImageView.constraint(equalTo: CGSize(width: 20, height: 20))
let disclosureConstraints = disclosureImageView.addConstraints(right: messageContainerView.rightAnchor, centerY: messageContainerView.centerYAnchor,
rightConstant: -10)
- disclosureConstraints.first?.identifier = ConstraintsID.disclouserRigtConstraint.rawValue
+ disclosureConstraints.first?.identifier = ConstraintsID.disclosureRigtConstraint.rawValue
nameLabel.addConstraints(messageContainerView.topAnchor,
left: initialsContainerView.rightAnchor,
bottom: messageContainerView.bottomAnchor,
@@ -120,15 +120,15 @@ open class ContactMessageCell: MessageContentCell {
let initialsContainerLeftConstraint = messageContainerView.constraints.filter { (constraint) -> Bool in
return constraint.identifier == ConstraintsID.initialsContainerLeftConstraint.rawValue
}.first
- let disclouserRightConstraint = messageContainerView.constraints.filter { (constraint) -> Bool in
- return constraint.identifier == ConstraintsID.disclouserRigtConstraint.rawValue
+ let disclosureRightConstraint = messageContainerView.constraints.filter { (constraint) -> Bool in
+ return constraint.identifier == ConstraintsID.disclosureRigtConstraint.rawValue
}.first
if dataSource.isFromCurrentSender(message: message) { // outgoing message
initialsContainerLeftConstraint?.constant = 5
- disclouserRightConstraint?.constant = -10
+ disclosureRightConstraint?.constant = -10
} else { // incoming message
initialsContainerLeftConstraint?.constant = 10
- disclouserRightConstraint?.constant = -5
+ disclosureRightConstraint?.constant = -5
}
// setup colors
guard let displayDelegate = messagesCollectionView.messagesDisplayDelegate else {
From 0c676da60ce036020de968ff96e8524fead08e75 Mon Sep 17 00:00:00 2001
From: Jakub Kaspar
Date: Thu, 2 Apr 2020 21:40:20 +0200
Subject: [PATCH 49/56] Fix swiftlint
---
.gitignore | 3 ++-
Dangerfile | 1 +
Example/Pods/SwiftLint/LICENSE | 21 +++++++++++++++++++++
Example/Pods/SwiftLint/swiftlint | Bin 0 -> 8417160 bytes
4 files changed, 24 insertions(+), 1 deletion(-)
create mode 100644 Example/Pods/SwiftLint/LICENSE
create mode 100755 Example/Pods/SwiftLint/swiftlint
diff --git a/.gitignore b/.gitignore
index 7cc39ae5..2ac6dbc1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,7 +29,8 @@ xcuserdata
*.ipa
# CocoaPods
-Pods/
+Example/Pods/*
+!Example/Pods/SwiftLint
# Carthage
Carthage
diff --git a/Dangerfile b/Dangerfile
index 3ef010fc..5d75a108 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -46,4 +46,5 @@ if git.lines_of_code > 1000
end
swiftlint.config_file = '.swiftlint.yml'
+swiftlint.binary_path = 'Example/Pods/SwiftLint/swiftlint'
swiftlint.lint_files inline_mode:true, fail_on_error:true
diff --git a/Example/Pods/SwiftLint/LICENSE b/Example/Pods/SwiftLint/LICENSE
new file mode 100644
index 00000000..04203762
--- /dev/null
+++ b/Example/Pods/SwiftLint/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2020 Realm Inc.
+
+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.
diff --git a/Example/Pods/SwiftLint/swiftlint b/Example/Pods/SwiftLint/swiftlint
new file mode 100755
index 0000000000000000000000000000000000000000..4213e41176aaa6ffb4545f335127abb501a749e8
GIT binary patch
literal 8417160
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