diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 5e149e68..bd9a2ab0 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -1,6 +1,10 @@ name: PR Danger -on: pull_request +on: + pull_request: + branches: + - master +# - development jobs: danger: diff --git a/.swiftlint.yml b/.swiftlint.yml index 5ebf9e77..f0172b38 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -13,7 +13,6 @@ custom_rules: severity: warning # violation severity. optional. opt_in_rules: - explicit_top_level_acl -explicit_acl: error explicit_top_level_acl: error included: - - Sources \ No newline at end of file + - Sources diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d2120a6..806c3249 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/MessageKit/MessageKit/releases) on GitHub. +## Upcoming release + +### Fixed + +### Added + +- Added option to use Photo messages with remote image URL in Example project [#1294](https://github.com/MessageKit/MessageKit/pull/1294) by [@martinpucik](https://github.com/martinpucik) + +### Changed + +- **Breaking Change** Dropped support for iOS 9 and iOS 10 [#1261](https://github.com/MessageKit/MessageKit/pull/1261) by [@kaspik](https://github.com/kaspik) + ## 3.1.0 ### Fixed diff --git a/Example/ChatExample.xcodeproj/project.pbxproj b/Example/ChatExample.xcodeproj/project.pbxproj index 89a85340..73778894 100644 --- a/Example/ChatExample.xcodeproj/project.pbxproj +++ b/Example/ChatExample.xcodeproj/project.pbxproj @@ -142,6 +142,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 13FCBEED2424D36900CB489F /* Resources */ = { + isa = PBXGroup; + children = ( + 882B5E7F1CF7D53600B6E160 /* Info.plist */, + 882B5E791CF7D53600B6E160 /* Assets.xcassets */, + 882B5E7A1CF7D53600B6E160 /* LaunchScreen.storyboard */, + ); + path = Resources; + sourceTree = ""; + }; 385C2924211FF3310010B4BA /* Views */ = { isa = PBXGroup; children = ( @@ -172,6 +182,7 @@ 385C2933211FF3670010B4BA /* Extensions */ = { isa = PBXGroup; children = ( + 385C292A211FF3450010B4BA /* Settings+UserDefaults.swift */, 385C292F211FF3630010B4BA /* UIColor+Extensions.swift */, 385C2930211FF3630010B4BA /* UIViewController+Extensions.swift */, ); @@ -259,17 +270,14 @@ children = ( 882B5E781CF7D53600B6E160 /* AppDelegate.swift */, 50739F9421C5075D008CA369 /* AudioController */, - 385C2949211FF3930010B4BA /* View Controllers */, 385C293A211FF3800010B4BA /* Data Generation */, + 385C2933211FF3670010B4BA /* Extensions */, 385C292E211FF3540010B4BA /* Layout */, 385C2929211FF33D0010B4BA /* Models */, - 385C2924211FF3310010B4BA /* Views */, + 13FCBEED2424D36900CB489F /* Resources */, 5074EF4B2163554900D82952 /* Sounds */, - 882B5E791CF7D53600B6E160 /* Assets.xcassets */, - 882B5E7F1CF7D53600B6E160 /* Info.plist */, - 882B5E7A1CF7D53600B6E160 /* LaunchScreen.storyboard */, - 385C292A211FF3450010B4BA /* Settings+UserDefaults.swift */, - 385C2933211FF3670010B4BA /* Extensions */, + 385C2949211FF3930010B4BA /* View Controllers */, + 385C2924211FF3310010B4BA /* Views */, ); path = Sources; sourceTree = ""; @@ -483,11 +491,17 @@ "${PODS_ROOT}/Target Support Files/Pods-ChatExample/Pods-ChatExample-frameworks.sh", "${BUILT_PRODUCTS_DIR}/InputBarAccessoryView/InputBarAccessoryView.framework", "${BUILT_PRODUCTS_DIR}/MessageKit/MessageKit.framework", + "${BUILT_PRODUCTS_DIR}/PINCache/PINCache.framework", + "${BUILT_PRODUCTS_DIR}/PINOperation/PINOperation.framework", + "${BUILT_PRODUCTS_DIR}/PINRemoteImage/PINRemoteImage.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/InputBarAccessoryView.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MessageKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINCache.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINOperation.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PINRemoteImage.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -523,7 +537,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -647,7 +661,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -699,7 +713,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; @@ -714,7 +728,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Resources/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.ChatExample; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -728,7 +742,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Sources/Resources/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.ChatExample; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme b/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme index 31f17b89..fec5e125 100644 --- a/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme +++ b/Example/ChatExample.xcodeproj/xcshareddata/xcschemes/ChatExample.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> + + + + @@ -54,17 +63,6 @@ - - - - - - - - - - - - = 0.8, < 2.0) netrc (~> 0.11) - cocoapods-try (1.1.0) + cocoapods-try (1.2.0) colored2 (3.1.2) concurrent-ruby (1.1.6) escape (0.0.4) @@ -71,9 +71,9 @@ GEM thread_safe (0.3.6) typhoeus (1.3.1) ethon (>= 0.9.0) - tzinfo (1.2.6) + tzinfo (1.2.7) thread_safe (~> 0.1) - xcodeproj (1.15.0) + xcodeproj (1.16.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/Example/Podfile b/Example/Podfile index 2e94b538..b8a13964 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,17 +1,18 @@ source 'https://cdn.cocoapods.org/' -platform :ios, '9.0' +platform :ios, '11.0' target 'ChatExample' do use_frameworks! pod 'MessageKit', :path => '../' + pod 'SwiftLint', '~> 0.39.1' + pod 'PINRemoteImage', '~> 3.0.0', :subspecs => ['iOS', 'PINCache'] -target 'ChatExampleTests' do - inherit! :search_paths -end - -target 'ChatExampleUITests' do - inherit! :search_paths -end + target 'ChatExampleTests' do + inherit! :search_paths + end + target 'ChatExampleUITests' do + inherit! :search_paths + end end diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 8bd75481..9a7af340 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -4,13 +4,36 @@ PODS: - InputBarAccessoryView/Core (4.3.2) - MessageKit (3.1.0): - InputBarAccessoryView (~> 4.3.0) + - PINCache (3.0.1-beta.8): + - PINCache/Arc-exception-safe (= 3.0.1-beta.8) + - PINCache/Core (= 3.0.1-beta.8) + - PINCache/Arc-exception-safe (3.0.1-beta.8): + - PINCache/Core + - PINCache/Core (3.0.1-beta.8): + - PINOperation (~> 1.1.1) + - PINOperation (1.1.2) + - PINRemoteImage/Core (3.0.0): + - PINOperation + - PINRemoteImage/iOS (3.0.0): + - PINRemoteImage/Core + - PINRemoteImage/PINCache (3.0.0): + - PINCache (= 3.0.1-beta.8) + - PINRemoteImage/Core + - SwiftLint (0.39.1) DEPENDENCIES: - MessageKit (from `../`) + - PINRemoteImage/iOS (~> 3.0.0) + - PINRemoteImage/PINCache (~> 3.0.0) + - SwiftLint (~> 0.39.1) SPEC REPOS: trunk: - InputBarAccessoryView + - PINCache + - PINOperation + - PINRemoteImage + - SwiftLint EXTERNAL SOURCES: MessageKit: @@ -18,8 +41,12 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: InputBarAccessoryView: 7985d418040a05fe894bd4b8328dd43ab35517c3 - MessageKit: 3beb578737a5aa2bba25cc27c7b6d6faa09af5a7 + MessageKit: 3c593dc22f7465f74822e4a873ef3157a3e05080 + PINCache: 534fd41d358d828dfdf227a0d327f3673a65e20b + PINOperation: 24b774353ca248fcf87d67b2d61eef42087c125a + PINRemoteImage: e2b89e19fb6e77ffc099f9d9f3b3fe1745e3f9f9 + SwiftLint: 55e96a4a4d537d4a3156859fc1c54bd24851a046 -PODFILE CHECKSUM: 90bd12ca685503630d7fe716609f4974660ed5ee +PODFILE CHECKSUM: cf0af8a506e2b58d4d51b99e165b58c56c26d619 COCOAPODS: 1.9.1 diff --git a/Example/Sources/Data Generation/SampleData.swift b/Example/Sources/Data Generation/SampleData.swift index 9fa50d29..525d05da 100644 --- a/Example/Sources/Data Generation/SampleData.swift +++ b/Example/Sources/Data Generation/SampleData.swift @@ -36,6 +36,7 @@ final internal class SampleData { case Text case AttributedText case Photo + case PhotoFromURL = "Photo from URL" case Video case Audio case Emoji @@ -69,6 +70,11 @@ final internal class SampleData { var now = Date() let messageImages: [UIImage] = [#imageLiteral(resourceName: "img1"), #imageLiteral(resourceName: "img2")] + let messageImageURLs: [URL] = [URL(string: "https://placekitten.com/g/200/300")!, + URL(string: "https://placekitten.com/g/300/300")!, + URL(string: "https://placekitten.com/g/300/400")!, + URL(string: "https://placekitten.com/g/400/400")!] + let emojis = [ "πŸ‘", "πŸ˜‚πŸ˜‚πŸ˜‚", @@ -143,21 +149,16 @@ final internal class SampleData { } func randomMessageType() -> MessageTypes { - var messageTypes = [MessageTypes]() - for type in MessageTypes.allCases { - if UserDefaults.standard.bool(forKey: "\(type.rawValue)" + " Messages") { - messageTypes.append(type) - } - } - return messageTypes.random()! + return MessageTypes.allCases.compactMap { + guard UserDefaults.standard.bool(forKey: "\($0.rawValue)" + " Messages") else { return nil } + return $0 + }.random()! } // swiftlint:disable cyclomatic_complexity func randomMessage(allowedSenders: [MockUser]) -> MockMessage { - let randomNumberSender = Int(arc4random_uniform(UInt32(allowedSenders.count))) - let uniqueID = UUID().uuidString - let user = allowedSenders[randomNumberSender] + let user = allowedSenders.random()! let date = dateAddingRandomTime() switch randomMessageType() { @@ -169,23 +170,21 @@ final internal class SampleData { let attributedText = attributedString(with: randomSentence) return MockMessage(attributedText: attributedText, user: user, messageId: uniqueID, date: date) case .Photo: - let randomNumberImage = Int(arc4random_uniform(UInt32(messageImages.count))) - let image = messageImages[randomNumberImage] + let image = messageImages.random()! return MockMessage(image: image, user: user, messageId: uniqueID, date: date) + case .PhotoFromURL: + let imageURL: URL = messageImageURLs.random()! + return MockMessage(imageURL: imageURL, user: user, messageId: uniqueID, date: date) case .Video: - let randomNumberImage = Int(arc4random_uniform(UInt32(messageImages.count))) - let image = messageImages[randomNumberImage] + let image = messageImages.random()! return MockMessage(thumbnail: image, user: user, messageId: uniqueID, date: date) case .Audio: - let randomNumberSound = Int(arc4random_uniform(UInt32(sounds.count))) - let soundURL = sounds[randomNumberSound] + let soundURL = sounds.random()! return MockMessage(audioURL: soundURL, user: user, messageId: uniqueID, date: date) case .Emoji: - let randomNumberEmoji = Int(arc4random_uniform(UInt32(emojis.count))) - return MockMessage(emoji: emojis[randomNumberEmoji], user: user, messageId: uniqueID, date: date) + return MockMessage(emoji: emojis.random()!, user: user, messageId: uniqueID, date: date) case .Location: - let randomNumberLocation = Int(arc4random_uniform(UInt32(locations.count))) - return MockMessage(location: locations[randomNumberLocation], user: user, messageId: uniqueID, date: date) + return MockMessage(location: locations.random()!, user: user, messageId: uniqueID, date: date) case .Url: return MockMessage(text: "https://github.com/MessageKit", user: user, messageId: uniqueID, date: date) case .Phone: @@ -193,8 +192,7 @@ final internal class SampleData { case .Custom: return MockMessage(custom: "Someone left the conversation", user: system, messageId: uniqueID, date: date) case .ShareContact: - let randomContact = Int(arc4random_uniform(UInt32(contactsToShare.count))) - return MockMessage(contact: contactsToShare[randomContact], user: user, messageId: uniqueID, date: date) + return MockMessage(contact: contactsToShare.random()!, user: user, messageId: uniqueID, date: date) } } // swiftlint:enable cyclomatic_complexity diff --git a/Example/Sources/Settings+UserDefaults.swift b/Example/Sources/Extensions/Settings+UserDefaults.swift similarity index 100% rename from Example/Sources/Settings+UserDefaults.swift rename to Example/Sources/Extensions/Settings+UserDefaults.swift diff --git a/Example/Sources/Models/MockMessage.swift b/Example/Sources/Models/MockMessage.swift index a5eb6ce1..82911b08 100644 --- a/Example/Sources/Models/MockMessage.swift +++ b/Example/Sources/Models/MockMessage.swift @@ -52,6 +52,11 @@ private struct ImageMediaItem: MediaItem { self.placeholderImage = UIImage() } + init(imageURL: URL) { + self.url = imageURL + self.size = CGSize(width: 240, height: 240) + self.placeholderImage = UIImage(imageLiteralResourceName: "image_message_placeholder") + } } private struct MockAudiotem: AudioItem { @@ -121,6 +126,11 @@ internal struct MockMessage: MessageType { self.init(kind: .photo(mediaItem), user: user, messageId: messageId, date: date) } + init(imageURL: URL, user: MockUser, messageId: String, date: Date) { + let mediaItem = ImageMediaItem(imageURL: imageURL) + self.init(kind: .photo(mediaItem), user: user, messageId: messageId, date: date) + } + init(thumbnail: UIImage, user: MockUser, messageId: String, date: Date) { let mediaItem = ImageMediaItem(image: thumbnail) self.init(kind: .video(mediaItem), user: user, messageId: messageId, date: date) diff --git a/Example/Sources/Models/MockSocket.swift b/Example/Sources/Models/MockSocket.swift index b23c5bcf..bdf1b63f 100644 --- a/Example/Sources/Models/MockSocket.swift +++ b/Example/Sources/Models/MockSocket.swift @@ -76,12 +76,10 @@ final class MockSocket { onNewMessageCode?(message) queuedMessage = nil } else { - let sender = arc4random_uniform(1) % 2 == 0 ? connectedUsers.first! : connectedUsers.last! - SampleData.shared.getMessages(count: 1, allowedSenders: [sender]) { (message) in - queuedMessage = message.first - } + let sender = connectedUsers.random()! + let message = SampleData.shared.randomMessage(allowedSenders: [sender]) + queuedMessage = message onTypingStatusCode?() } } - } diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-1024.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@2x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-20@3x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@2x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-29@3x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@2x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-40@3x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@2x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-60@3x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-76@2x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/30243544-83.5@2x.png diff --git a/Example/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Example/Sources/Assets.xcassets/Contents.json b/Example/Sources/Resources/Assets.xcassets/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/Contents.json rename to Example/Sources/Resources/Assets.xcassets/Contents.json diff --git a/Example/Sources/Assets.xcassets/Dan-Leonard.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/Dan-Leonard.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg b/Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg similarity index 100% rename from Example/Sources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg rename to Example/Sources/Resources/Assets.xcassets/Dan-Leonard.imageset/NiceSelfi.jpg diff --git a/Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg b/Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg similarity index 100% rename from Example/Sources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg rename to Example/Sources/Resources/Assets.xcassets/Nathan-Tannar.imageset/Nathan.jpg diff --git a/Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg b/Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg similarity index 100% rename from Example/Sources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg rename to Example/Sources/Resources/Assets.xcassets/Steve-Jobs.imageset/Steve-Jobs.jpeg diff --git a/Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg b/Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg similarity index 100% rename from Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg rename to Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/7445580.jpeg diff --git a/Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/Steven-Deutsch.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/Tim-Cook.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/Tim-Cook.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg b/Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg similarity index 100% rename from Example/Sources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg rename to Example/Sources/Resources/Assets.xcassets/Tim-Cook.imageset/Tim-Cook.jpeg diff --git a/Example/Sources/Assets.xcassets/Wu-Zhong.imageset/5061845.png b/Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/5061845.png similarity index 100% rename from Example/Sources/Assets.xcassets/Wu-Zhong.imageset/5061845.png rename to Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/5061845.png diff --git a/Example/Sources/Assets.xcassets/Wu-Zhong.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/Wu-Zhong.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/Wu-Zhong.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_appstore.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_appstore.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png b/Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png rename to Example/Sources/Resources/Assets.xcassets/ic_appstore.imageset/icons8-apple_app_store_filled.png diff --git a/Example/Sources/Assets.xcassets/ic_at.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_at.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_at.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_at.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_at.imageset/icons8-email.png b/Example/Sources/Resources/Assets.xcassets/ic_at.imageset/icons8-email.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_at.imageset/icons8-email.png rename to Example/Sources/Resources/Assets.xcassets/ic_at.imageset/icons8-email.png diff --git a/Example/Sources/Assets.xcassets/ic_camera.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_camera.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_camera.imageset/icons8-camera.png b/Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/icons8-camera.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_camera.imageset/icons8-camera.png rename to Example/Sources/Resources/Assets.xcassets/ic_camera.imageset/icons8-camera.png diff --git a/Example/Sources/Assets.xcassets/ic_hashtag.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_hashtag.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png b/Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png rename to Example/Sources/Resources/Assets.xcassets/ic_hashtag.imageset/icons8-hashtag.png diff --git a/Example/Sources/Assets.xcassets/ic_info.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_info.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_info.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_info.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_info.imageset/icons8-info.png b/Example/Sources/Resources/Assets.xcassets/ic_info.imageset/icons8-info.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_info.imageset/icons8-info.png rename to Example/Sources/Resources/Assets.xcassets/ic_info.imageset/icons8-info.png diff --git a/Example/Sources/Assets.xcassets/ic_keyboard.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_keyboard.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png b/Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png rename to Example/Sources/Resources/Assets.xcassets/ic_keyboard.imageset/icons8-keyboard.png diff --git a/Example/Sources/Assets.xcassets/ic_library.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_library.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_library.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_library.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png b/Example/Sources/Resources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png rename to Example/Sources/Resources/Assets.xcassets/ic_library.imageset/icons8-medium_icons.png diff --git a/Example/Sources/Assets.xcassets/ic_like.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_like.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_like.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_like.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_like.imageset/icons8-like_it.png b/Example/Sources/Resources/Assets.xcassets/ic_like.imageset/icons8-like_it.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_like.imageset/icons8-like_it.png rename to Example/Sources/Resources/Assets.xcassets/ic_like.imageset/icons8-like_it.png diff --git a/Example/Sources/Assets.xcassets/ic_map_marker.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_map_marker.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png b/Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png rename to Example/Sources/Resources/Assets.xcassets/ic_map_marker.imageset/icons8-map_pin-1.png diff --git a/Example/Sources/Assets.xcassets/ic_mic.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_mic.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png b/Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png rename to Example/Sources/Resources/Assets.xcassets/ic_mic.imageset/icons8-microphone.png diff --git a/Example/Sources/Assets.xcassets/ic_send.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_send.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_send.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_send.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_send.imageset/icons8-sent.png b/Example/Sources/Resources/Assets.xcassets/ic_send.imageset/icons8-sent.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_send.imageset/icons8-sent.png rename to Example/Sources/Resources/Assets.xcassets/ic_send.imageset/icons8-sent.png diff --git a/Example/Sources/Assets.xcassets/ic_typing.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_typing.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png b/Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png rename to Example/Sources/Resources/Assets.xcassets/ic_typing.imageset/icons8-hand_with_pen.png diff --git a/Example/Sources/Assets.xcassets/ic_up.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/ic_up.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/ic_up.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/ic_up.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png b/Example/Sources/Resources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png similarity index 100% rename from Example/Sources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png rename to Example/Sources/Resources/Assets.xcassets/ic_up.imageset/icons8-up_arrow.png diff --git a/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/Contents.json new file mode 100644 index 00000000..ade8d418 --- /dev/null +++ b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "image_message_placeholder.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/image_message_placeholder.pdf b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/image_message_placeholder.pdf new file mode 100644 index 00000000..69de86ee Binary files /dev/null and b/Example/Sources/Resources/Assets.xcassets/image_message_placeholder.imageset/image_message_placeholder.pdf differ diff --git a/Example/Sources/Assets.xcassets/img1.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/img1.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/img1.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/img1.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg b/Example/Sources/Resources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg similarity index 100% rename from Example/Sources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg rename to Example/Sources/Resources/Assets.xcassets/img1.imageset/grey-crowned-crane-bird-crane-animal-45853.jpeg diff --git a/Example/Sources/Assets.xcassets/img2.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/img2.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/img2.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/img2.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg b/Example/Sources/Resources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg similarity index 100% rename from Example/Sources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg rename to Example/Sources/Resources/Assets.xcassets/img2.imageset/pexels-photo-145939.jpeg diff --git a/Example/Sources/Assets.xcassets/mklogo.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/mklogo.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/mklogo.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/mklogo.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/mklogo.imageset/mklogo.png b/Example/Sources/Resources/Assets.xcassets/mklogo.imageset/mklogo.png similarity index 100% rename from Example/Sources/Assets.xcassets/mklogo.imageset/mklogo.png rename to Example/Sources/Resources/Assets.xcassets/mklogo.imageset/mklogo.png diff --git a/Example/Sources/Assets.xcassets/mkorglogo.imageset/30243544.png b/Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/30243544.png similarity index 100% rename from Example/Sources/Assets.xcassets/mkorglogo.imageset/30243544.png rename to Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/30243544.png diff --git a/Example/Sources/Assets.xcassets/mkorglogo.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/mkorglogo.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/mkorglogo.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/pin.imageset/Contents.json b/Example/Sources/Resources/Assets.xcassets/pin.imageset/Contents.json similarity index 100% rename from Example/Sources/Assets.xcassets/pin.imageset/Contents.json rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/Contents.json diff --git a/Example/Sources/Assets.xcassets/pin.imageset/pin.png b/Example/Sources/Resources/Assets.xcassets/pin.imageset/pin.png similarity index 100% rename from Example/Sources/Assets.xcassets/pin.imageset/pin.png rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/pin.png diff --git a/Example/Sources/Assets.xcassets/pin.imageset/pin@2x.png b/Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@2x.png similarity index 100% rename from Example/Sources/Assets.xcassets/pin.imageset/pin@2x.png rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@2x.png diff --git a/Example/Sources/Assets.xcassets/pin.imageset/pin@3x.png b/Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@3x.png similarity index 100% rename from Example/Sources/Assets.xcassets/pin.imageset/pin@3x.png rename to Example/Sources/Resources/Assets.xcassets/pin.imageset/pin@3x.png diff --git a/Example/Sources/Base.lproj/LaunchScreen.storyboard b/Example/Sources/Resources/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from Example/Sources/Base.lproj/LaunchScreen.storyboard rename to Example/Sources/Resources/Base.lproj/LaunchScreen.storyboard diff --git a/Example/Sources/Info.plist b/Example/Sources/Resources/Info.plist similarity index 100% rename from Example/Sources/Info.plist rename to Example/Sources/Resources/Info.plist diff --git a/Example/Sources/View Controllers/AdvancedExampleViewController.swift b/Example/Sources/View Controllers/AdvancedExampleViewController.swift index 9cff3da1..a77d1bf0 100644 --- a/Example/Sources/View Controllers/AdvancedExampleViewController.swift +++ b/Example/Sources/View Controllers/AdvancedExampleViewController.swift @@ -26,6 +26,7 @@ import UIKit import MapKit import MessageKit import InputBarAccessoryView +import PINRemoteImage final class AdvancedExampleViewController: ChatViewController { @@ -353,6 +354,14 @@ extension AdvancedExampleViewController: MessagesDisplayDelegate { accessoryView.layer.cornerRadius = accessoryView.frame.height / 2 accessoryView.backgroundColor = UIColor.primaryColor.withAlphaComponent(0.3) } + + func configureMediaMessageImageView(_ imageView: UIImageView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) { + if case MessageKind.photo(let media) = message.kind, let imageURL = media.url { + imageView.pin_setImage(from: imageURL) + } else { + imageView.pin_cancelImageDownload() + } + } // MARK: - Location Messages diff --git a/Example/Sources/View Controllers/AutocompleteExampleViewController.swift b/Example/Sources/View Controllers/AutocompleteExampleViewController.swift index c4941db4..f50090aa 100644 --- a/Example/Sources/View Controllers/AutocompleteExampleViewController.swift +++ b/Example/Sources/View Controllers/AutocompleteExampleViewController.swift @@ -9,6 +9,7 @@ import UIKit import MessageKit import InputBarAccessoryView +import PINRemoteImage final class AutocompleteExampleViewController: ChatViewController { @@ -336,6 +337,14 @@ extension AutocompleteExampleViewController: MessagesDisplayDelegate { accessoryView.layer.cornerRadius = accessoryView.frame.height / 2 accessoryView.backgroundColor = UIColor.primaryColor.withAlphaComponent(0.3) } + + func configureMediaMessageImageView(_ imageView: UIImageView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) { + if case MessageKind.photo(let media) = message.kind, let imageURL = media.url { + imageView.pin_setImage(from: imageURL) + } else { + imageView.pin_cancelImageDownload() + } + } } // MARK: - MessagesLayoutDelegate diff --git a/Example/Sources/View Controllers/BasicExampleViewController.swift b/Example/Sources/View Controllers/BasicExampleViewController.swift index 98e81d55..dec927c7 100644 --- a/Example/Sources/View Controllers/BasicExampleViewController.swift +++ b/Example/Sources/View Controllers/BasicExampleViewController.swift @@ -25,6 +25,7 @@ import UIKit import MapKit import MessageKit +import PINRemoteImage final class BasicExampleViewController: ChatViewController { override func configureMessageCollectionView() { @@ -71,6 +72,14 @@ extension BasicExampleViewController: MessagesDisplayDelegate { let avatar = SampleData.shared.getAvatarFor(sender: message.sender) avatarView.set(avatar: avatar) } + + func configureMediaMessageImageView(_ imageView: UIImageView, for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) { + if case MessageKind.photo(let media) = message.kind, let imageURL = media.url { + imageView.pin_setImage(from: imageURL) + } else { + imageView.pin_cancelImageDownload() + } + } // MARK: - Location Messages diff --git a/Example/Sources/View Controllers/ChatViewController.swift b/Example/Sources/View Controllers/ChatViewController.swift index 71c853ed..aef82746 100644 --- a/Example/Sources/View Controllers/ChatViewController.swift +++ b/Example/Sources/View Controllers/ChatViewController.swift @@ -1,7 +1,7 @@ /* MIT License -Copyright (c) 2017-2019 MessageKit +Copyright (c) 2017-2020 MessageKit Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -28,24 +28,30 @@ import InputBarAccessoryView /// A base class for the example controllers class ChatViewController: MessagesViewController, MessagesDataSource { - - override var preferredStatusBarStyle: UIStatusBarStyle { - return .lightContent - } - - /// The `BasicAudioController` controll the AVAudioPlayer state (play, pause, stop) and udpate audio cell UI accordingly. - open lazy var audioController = BasicAudioController(messageCollectionView: messagesCollectionView) - var messageList: [MockMessage] = [] + // MARK: - Public properties + + /// The `BasicAudioController` controll the AVAudioPlayer state (play, pause, stop) and udpate audio cell UI accordingly. + lazy var audioController = BasicAudioController(messageCollectionView: messagesCollectionView) + + lazy var messageList: [MockMessage] = [] - let refreshControl = UIRefreshControl() - - let formatter: DateFormatter = { + private(set) lazy var refreshControl: UIRefreshControl = { + let control = UIRefreshControl() + control.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged) + return control + }() + + // MARK: - Private properties + + private let formatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .medium return formatter }() - + + // MARK: - Lifecycle + override func viewDidLoad() { super.viewDidLoad() @@ -69,6 +75,10 @@ class ChatViewController: MessagesViewController, MessagesDataSource { MockSocket.shared.disconnect() audioController.stopAnyOngoingPlaying() } + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } func loadFirstMessages() { DispatchQueue.global(qos: .userInitiated).async { @@ -83,8 +93,7 @@ class ChatViewController: MessagesViewController, MessagesDataSource { } } - @objc - func loadMoreMessages() { + @objc func loadMoreMessages() { DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 1) { SampleData.shared.getMessages(count: 20) { messages in DispatchQueue.main.async { @@ -104,8 +113,7 @@ class ChatViewController: MessagesViewController, MessagesDataSource { scrollsToBottomOnKeyboardBeginsEditing = true // default false maintainPositionOnKeyboardFrameChanged = true // default false - messagesCollectionView.addSubview(refreshControl) - refreshControl.addTarget(self, action: #selector(loadMoreMessages), for: .valueChanged) + messagesCollectionView.refreshControl = refreshControl } func configureMessageInputBar() { @@ -143,50 +151,46 @@ class ChatViewController: MessagesViewController, MessagesDataSource { return messagesCollectionView.indexPathsForVisibleItems.contains(lastIndexPath) } - + // MARK: - MessagesDataSource - + func currentSender() -> SenderType { return SampleData.shared.currentSender } - + func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int { return messageList.count } - + func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType { return messageList[indexPath.section] } - + func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? { if indexPath.section % 3 == 0 { return NSAttributedString(string: MessageKitDateFormatter.shared.string(from: message.sentDate), attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedString.Key.foregroundColor: UIColor.darkGray]) } return nil } - + func cellBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? { - return NSAttributedString(string: "Read", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedString.Key.foregroundColor: UIColor.darkGray]) } - + func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? { let name = message.sender.displayName return NSAttributedString(string: name, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption1)]) } - + func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? { - let dateString = formatter.string(from: message.sentDate) return NSAttributedString(string: dateString, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)]) } - } // MARK: - MessageCellDelegate extension ChatViewController: MessageCellDelegate { - func didTapAvatar(in cell: MessageCollectionViewCell) { print("Avatar tapped") } @@ -261,7 +265,6 @@ extension ChatViewController: MessageCellDelegate { // MARK: - MessageLabelDelegate extension ChatViewController: MessageLabelDelegate { - func didSelectAddress(_ addressComponents: [String: String]) { print("Address Selected: \(addressComponents)") } @@ -293,15 +296,12 @@ extension ChatViewController: MessageLabelDelegate { func didSelectCustom(_ pattern: String, match: String?) { print("Custom data detector patter selected: \(pattern)") } - } // MARK: - MessageInputBarDelegate extension ChatViewController: InputBarAccessoryViewDelegate { - func inputBar(_ inputBar: InputBarAccessoryView, didPressSendButtonWith text: String) { - // Here we can parse for which substrings were autocompleted let attributedText = messageInputBar.inputTextView.attributedText! let range = NSRange(location: 0, length: attributedText.length) diff --git a/Example/Sources/View Controllers/LaunchViewController.swift b/Example/Sources/View Controllers/LaunchViewController.swift index 50794115..fc25609b 100644 --- a/Example/Sources/View Controllers/LaunchViewController.swift +++ b/Example/Sources/View Controllers/LaunchViewController.swift @@ -46,16 +46,12 @@ final internal class LaunchViewController: UITableViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - if #available(iOS 11.0, *) { - navigationController?.navigationBar.prefersLargeTitles = true - } + navigationController?.navigationBar.prefersLargeTitles = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - if #available(iOS 11.0, *) { - navigationController?.navigationBar.prefersLargeTitles = false - } + navigationController?.navigationBar.prefersLargeTitles = false } // MARK: - UITableViewDataSource @@ -100,9 +96,7 @@ final internal class LaunchViewController: UITableViewController { func openURL(_ url: URL) { let webViewController = SFSafariViewController(url: url) - if #available(iOS 10.0, *) { - webViewController.preferredControlTintColor = .primaryColor - } + webViewController.preferredControlTintColor = .primaryColor present(webViewController, animated: true, completion: nil) } } diff --git a/Example/Sources/View Controllers/NavigationController.swift b/Example/Sources/View Controllers/NavigationController.swift index cc2d7eb2..c47cace5 100644 --- a/Example/Sources/View Controllers/NavigationController.swift +++ b/Example/Sources/View Controllers/NavigationController.swift @@ -36,9 +36,7 @@ final class NavigationController: UINavigationController { navigationBar.tintColor = .white navigationBar.barTintColor = .primaryColor navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] - if #available(iOS 11.0, *) { - navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white] - } + navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white] navigationBar.shadowImage = UIImage() navigationBar.setBackgroundImage(UIImage(), for: .default) view.backgroundColor = .primaryColor @@ -50,17 +48,13 @@ final class NavigationController: UINavigationController { navigationBar.barTintColor = .primaryColor navigationBar.tintColor = .white navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] - if #available(iOS 11.0, *) { - navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white] - } + navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.white] } else if style == .lightContent { navigationBar.shadowImage = nil navigationBar.barTintColor = .white navigationBar.tintColor = UIColor(red: 0, green: 0.5, blue: 1, alpha: 1) navigationBar.titleTextAttributes = [.foregroundColor: UIColor.black] - if #available(iOS 11.0, *) { - navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.black] - } + navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.black] } } diff --git a/Example/Sources/View Controllers/SettingsViewController.swift b/Example/Sources/View Controllers/SettingsViewController.swift index 92235e52..137e1f3a 100644 --- a/Example/Sources/View Controllers/SettingsViewController.swift +++ b/Example/Sources/View Controllers/SettingsViewController.swift @@ -33,7 +33,7 @@ final internal class SettingsViewController: UITableViewController { return .lightContent } - let cells = ["Mock messages count", "Text Messages", "AttributedText Messages", "Photo Messages", "Video Messages", "Audio Messages", "Emoji Messages", "Location Messages", "Url Messages", "Phone Messages", "ShareContact Messages"] + let cells = ["Mock messages count", "Text Messages", "AttributedText Messages", "Photo Messages", "Photo from URL Messages", "Video Messages", "Audio Messages", "Emoji Messages", "Location Messages", "Url Messages", "Phone Messages", "ShareContact Messages"] // MARK: - Picker diff --git a/Example/UITests/ChatExampleUITests.swift b/Example/UITests/ChatExampleUITests.swift index d9548ce9..df4df727 100644 --- a/Example/UITests/ChatExampleUITests.swift +++ b/Example/UITests/ChatExampleUITests.swift @@ -28,11 +28,7 @@ final class ChatExampleUITests: XCTestCase { continueAfterFailure = false // UI tests must launch the application that they test. // Doing this in setup will make sure it happens for each test method. - if #available(iOS 9.0, *) { - XCUIApplication().launch() - } else { - // Fallback on earlier versions - } + XCUIApplication().launch() // In UI tests it’s important to set the initial state // - such as interface orientation - required for your tests before they run. diff --git a/Gemfile.lock b/Gemfile.lock index a1f1e31d..92d07b5d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -30,11 +30,12 @@ GEM thor (~> 0.19) faraday (0.17.3) multipart-post (>= 1.2, < 3) - faraday-http-cache (2.0.0) - faraday (~> 0.8) + faraday-http-cache (2.2.0) + faraday (>= 0.8) git (1.6.0) rchardet (~> 1.8) - kramdown (2.1.0) + kramdown (2.2.1) + rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) multipart-post (2.1.1) @@ -44,9 +45,10 @@ GEM faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) open4 (1.3.4) - public_suffix (4.0.3) + public_suffix (4.0.4) rake (13.0.1) rchardet (1.8.0) + rexml (3.2.4) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) diff --git a/LICENSE.md b/LICENSE.md index 21660f30..20cc288d 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017-2019 MessageKit +Copyright (c) 2017-2020 MessageKit Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/MessageKit.podspec b/MessageKit.podspec index 06b1f220..dfe3a5a0 100644 --- a/MessageKit.podspec +++ b/MessageKit.podspec @@ -11,17 +11,11 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/MessageKit/MessageKit.git', :tag => s.version } s.source_files = 'Sources/**/*.swift' - s.pod_target_xcconfig = { - "SWIFT_VERSION" => "5.0", - } - s.swift_version = '5.0' - s.ios.deployment_target = '9.0' + s.ios.deployment_target = '11.0' s.ios.resource_bundle = { 'MessageKitAssets' => 'Assets/MessageKitAssets.bundle/Images' } - s.requires_arc = true - s.dependency 'InputBarAccessoryView', '~> 4.3.0' end diff --git a/MessageKit.xcodeproj/project.pbxproj b/MessageKit.xcodeproj/project.pbxproj index 72509f16..d4823309 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 */, ); @@ -783,7 +783,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -838,7 +838,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_VERSION = 5.0; @@ -865,7 +865,6 @@ GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/Supporting/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.MessageKit; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -891,7 +890,6 @@ GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/Supporting/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; PRODUCT_BUNDLE_IDENTIFIER = com.messagekit.MessageKit; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/README.md b/README.md index 425ff0c9..75ff53be 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

[![CircleCI](https://circleci.com/gh/MessageKit/MessageKit.svg?style=svg)](https://circleci.com/gh/MessageKit/MessageKit) -[![codecov](https://codecov.io/gh/MessageKit/MessageKit/branch/master/graph/badge.svg)](https://codecov.io/gh/MessageKit/MessageKit) +[![codecov](https://codecov.io/gh/MessageKit/MessageKit/branch/development/graph/badge.svg)](https://codecov.io/gh/MessageKit/MessageKit) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) Swift @@ -58,7 +58,7 @@ To integrate MessageKit using Carthage, add the following to your `Cartfile`: github "MessageKit/MessageKit" ```` -### [Manual]([https://github.com/MessageKit/MessageKit/blob/master/Documentation/MANUAL_INSTALLATION.md) +### [Manual](https://github.com/MessageKit/MessageKit/blob/master/Documentation/MANUAL_INSTALLATION.md) ## Requirements diff --git a/Sources/Controllers/MessagesViewController+Keyboard.swift b/Sources/Controllers/MessagesViewController+Keyboard.swift index 2abbd030..bb905d3e 100644 --- a/Sources/Controllers/MessagesViewController+Keyboard.swift +++ b/Sources/Controllers/MessagesViewController+Keyboard.swift @@ -32,7 +32,6 @@ internal extension MessagesViewController { func addKeyboardObservers() { NotificationCenter.default.addObserver(self, selector: #selector(MessagesViewController.handleKeyboardDidChangeState(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(MessagesViewController.handleTextViewDidBeginEditing(_:)), name: UITextView.textDidBeginEditingNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(MessagesViewController.adjustScrollViewTopInset), name: UIDevice.orientationDidChangeNotification, object: nil) } func removeKeyboardObservers() { @@ -105,19 +104,6 @@ internal extension MessagesViewController { // MARK: - Inset Computation - @objc - func adjustScrollViewTopInset() { - if #available(iOS 11.0, *) { - // No need to add to the top contentInset - } else { - let navigationBarInset = navigationController?.navigationBar.frame.height ?? 0 - let statusBarInset: CGFloat = UIApplication.shared.isStatusBarHidden ? 0 : 20 - let topInset = navigationBarInset + statusBarInset - messagesCollectionView.contentInset.top = topInset - messagesCollectionView.scrollIndicatorInsets.top = topInset - } - } - private func requiredScrollViewBottomInset(forKeyboardFrame keyboardFrame: CGRect) -> CGFloat { // we only need to adjust for the part of the keyboard that covers (i.e. intersects) our collection view; // see https://developer.apple.com/videos/play/wwdc2017/242/ for more details @@ -137,16 +123,11 @@ internal extension MessagesViewController { return max(0, inputAccessoryViewHeight + additionalBottomInset - automaticallyAddedBottomInset) } - /// iOS 11's UIScrollView can automatically add safe area insets to its contentInset, + /// UIScrollView can automatically add safe area insets to its contentInset, /// which needs to be accounted for when setting the contentInset based on screen coordinates. /// /// - Returns: The distance automatically added to contentInset.bottom, if any. private var automaticallyAddedBottomInset: CGFloat { - if #available(iOS 11.0, *) { - return messagesCollectionView.adjustedContentInset.bottom - messagesCollectionView.contentInset.bottom - } else { - return 0 - } + return messagesCollectionView.adjustedContentInset.bottom - messagesCollectionView.contentInset.bottom } - } diff --git a/Sources/Controllers/MessagesViewController.swift b/Sources/Controllers/MessagesViewController.swift index e74b0183..522997ed 100644 --- a/Sources/Controllers/MessagesViewController.swift +++ b/Sources/Controllers/MessagesViewController.swift @@ -130,13 +130,10 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { addKeyboardObservers() messageCollectionViewBottomInset = requiredInitialScrollViewBottomInset() } - adjustScrollViewTopInset() } open override func viewSafeAreaInsetsDidChange() { - if #available(iOS 11.0, *) { - super.viewSafeAreaInsetsDidChange() - } + super.viewSafeAreaInsetsDidChange() messageCollectionViewBottomInset = requiredInitialScrollViewBottomInset() } @@ -153,8 +150,8 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { private func setupDefaults() { extendedLayoutIncludesOpaqueBars = true - automaticallyAdjustsScrollViewInsets = false view.backgroundColor = .backgroundColor + messagesCollectionView.contentInsetAdjustmentBehavior = .never messagesCollectionView.keyboardDismissMode = .interactive messagesCollectionView.alwaysBounceVertical = true messagesCollectionView.backgroundColor = .backgroundColor @@ -172,17 +169,11 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { private func setupConstraints() { messagesCollectionView.translatesAutoresizingMaskIntoConstraints = false - let top = messagesCollectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: topLayoutGuide.length) + let top = messagesCollectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor) let bottom = messagesCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) - if #available(iOS 11.0, *) { - let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor) - let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor) - NSLayoutConstraint.activate([top, bottom, trailing, leading]) - } else { - let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor) - let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor) - NSLayoutConstraint.activate([top, bottom, trailing, leading]) - } + let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor) + let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor) + NSLayoutConstraint.activate([top, bottom, trailing, leading]) } // MARK: - Typing Indicator API diff --git a/Sources/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/Models/AccessoryPosition.swift b/Sources/Models/AccessoryPosition.swift index 04092026..cd2c486e 100644 --- a/Sources/Models/AccessoryPosition.swift +++ b/Sources/Models/AccessoryPosition.swift @@ -25,7 +25,7 @@ import Foundation /// Used to determine the `Horizontal` and `Vertical` position of -// an `AccessoryView` in a `MessageCollectionViewCell`. +/// an `AccessoryView` in a `MessageCollectionViewCell`. public enum AccessoryPosition { /// Aligns the `AccessoryView`'s top edge to the cell's top edge. diff --git a/Sources/Views/Cells/ContactMessageCell.swift b/Sources/Views/Cells/ContactMessageCell.swift index 2273a834..531d089d 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 disclosureRightConstraint } /// 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.disclosureRightConstraint.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.disclosureRightConstraint.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 { 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()) }