diff --git a/.circleci/config.yml b/.circleci/config.yml index effab375f..d9eb789c1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ defaults: &defaults macos: - xcode: "11.6.0" + xcode: "11.7.0" shell: /bin/bash --login -eo pipefail aliases: - &cache-pull @@ -25,38 +25,6 @@ aliases: version: 2 jobs: - ios: - <<: *defaults - steps: - - checkout - - restore_cache: *cache-pull - - run: *prepare - - save_cache: *cache-push - - run: bundle exec rake test:ios - - run: bash <(curl -s https://codecov.io/bash) - - store_test_results: - path: build/reports - macos: - <<: *defaults - steps: - - checkout - - restore_cache: *cache-pull - - run: *prepare - - save_cache: *cache-push - - run: - name: "Create and set the default keychain" - command: | - security create-keychain -p "" temporary - security default-keychain -s temporary - security unlock-keychain -p "" temporary - security set-keychain-settings -lut 7200 temporary - - run: bundle exec rake test:macos - - run: bash <(curl -s https://codecov.io/bash) - - store_test_results: - path: build/reports - - store_artifacts: - path: build/reports - destination: test_results carthage: <<: *defaults steps: @@ -70,8 +38,6 @@ workflows: version: 2 pr: jobs: - - ios - - macos - carthage nightly: jobs: diff --git a/.codecov.yml b/.codecov.yml index 1b84209f7..da2f08dec 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -8,5 +8,5 @@ coverage: changes: false project: default: - target: 65 + target: 74 comment: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..2d76e1622 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,186 @@ +name: ci +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] +env: + CI_XCODE_VER: '/Applications/Xcode_11.7.app/Contents/Developer' + CI_XCODE_VER_OLDER: '/Applications/Xcode_11.6.app/Contents/Developer' + +jobs: + ios: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Install + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config set path 'vendor/bundle' + bundle install + - name: Build-Test + run: set -o pipefail && env NSUnbufferedIO=YES bundle exec rake test:ios + - name: Send codecov + run: bash <(curl https://codecov.io/bash) + + macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Install + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config set path 'vendor/bundle' + bundle install + - name: Create and set the default keychain + run: | + security create-keychain -p "" temporary + security default-keychain -s temporary + security unlock-keychain -p "" temporary + security set-keychain-settings -lut 7200 temporary + - name: Build-Test + run: set -o pipefail && env NSUnbufferedIO=YES bundle exec rake test:macos + - name: Send codecov + run: bash <(curl https://codecov.io/bash) + + facebook_utils: + needs: macos + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Install + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config set path 'vendor/bundle' + bundle install + - name: Build-Test + run: set -o pipefail && env NSUnbufferedIO=YES bundle exec rake test:facebook_utils:ios + - name: Send codecov + run: bash <(curl https://codecov.io/bash) + + twitter_utils: + needs: macos + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Install + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config set path 'vendor/bundle' + bundle install + - name: Build-Test + run: set -o pipefail && env NSUnbufferedIO=YES bundle exec rake test:twitter_utils:ios + - name: Send codecov + run: bash <(curl https://codecov.io/bash) + + parseui: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Install + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config set path 'vendor/bundle' + bundle install + - name: Build-Test + run: set -o pipefail && env NSUnbufferedIO=YES bundle exec rake test:parseui:all + - name: Send codecov + run: bash <(curl https://codecov.io/bash) + + cocoapods: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: CocoaPods + run: set -o pipefail && env NSUnbufferedIO=YES pod lib lint --allow-warnings --verbose + + release: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Install + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config set path 'vendor/bundle' + bundle install + - name: Build Release + run: set -o pipefail && env NSUnbufferedIO=YES bundle exec rake package:release + env: + DEVELOPER_DIR: ${{ env.CI_XCODE_VER }} + + docs: + needs: macos + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Instal + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config path vendor/bundle + bundle install + - name: Create Jazzy Docs + run: | + ./Scripts/jazzy.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..a1ba0c30a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,77 @@ +name: release +on: + release: + types: [published] +env: + CI_XCODE_VER: '/Applications/Xcode_11.7.app/Contents/Developer' + +jobs: + cocoapods: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: CocoaPods + run: set -o pipefail && env NSUnbufferedIO=YES pod lib lint --allow-warnings --verbose + - name: Deploy CocoaPods + run: set -o pipefail && env NSUnbufferedIO=YES pod trunk push Parse.podspec --allow-warnings --verbose + env: + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} + DEVELOPER_DIR: ${{ env.CI_XCODE_VER }} + + docs: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Install Bundle + run: | + bundle config path vendor/bundle + bundle install + - name: Create Jazzy Docs + run: | + ./Scripts/jazzy.sh + env: + DEVELOPER_DIR: ${{ env.CI_XCODE_VER }} + - name: Deploy Jazzy Docs + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs + + release: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Cache Gems + id: cache-gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-gem- + - name: Submodules and Bundle Install + run: | + git submodule update --init --recursive + sudo gem install bundler + bundle config set path 'vendor/bundle' + bundle install + - name: Build Release + run: set -o pipefail && env NSUnbufferedIO=YES bundle exec rake package:release + env: + DEVELOPER_DIR: ${{ env.CI_XCODE_VER }} + - name: Deploy assets + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: build/release/* + tag: ${{ github.ref }} + overwrite: true + file_glob: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8b7879a91..000000000 --- a/.travis.yml +++ /dev/null @@ -1,87 +0,0 @@ -language: objective-c -os: osx -osx_image: xcode11.6 -branches: - only: - - master - - /^v?[0-9]+\.[0-9]+\.[0-9]+(-.*)?$/ -cache: - directories: - - vendor/bundle - -jobs: - include: - - stage: release - env: Deployment - install: - - bundle config set path 'vendor/bundle' - - travis_wait bundle install - script: - - bundle exec rake package:release - deploy: - - provider: releases - token: - secure: m7YayvmctH5lyHj13EV2j898P5xfEfN/ZvFm2gL/xveTNOGaET1O4ZmGmHApxC2QwIZvtwmO3U9pmB4XVVQ7kIlTsl01h84y8gx1XQqEKoQINcaVaNCsh9EdxAqj08aiwe/1dp8W8rI/ptOrxzWJDWcxKx5tMIbBzctGeL3GDKphVvD44s43oosqQCKzP+qHiI6rRRxu+0QccdbTagwd0X/yaLZ0IbTo35hWFEyJ6NfJnmCW/lNwWj86YksLCZx0eKdxUSQlIhnm0upTyowudt9bv8vSdEYi2AtRKoana/X53593O8RAVEc+S6NgMmeQ1/ZD1eDeyYLzN/z21EHb4yiwTnMUUhDBMTn8KKTiiSVDQOfAyRwtKF+1qN2iDr9Dh3A8+dCxOxJJpIPImZimt8KMCKB9WTtnJhvIoMCDpc8l29XM/oBxjCiBFxPClb9CZ74T5b+xl+yIqy2u8RiaZ1Va5vmWjMSXDsGHoZ0rJTOBkBBhyr+47yIw2VeY2z2q5hiALV3DnE5Esxyddhw7OXNZcvKriujnxcTOJwphm4XBMI/3rSH27uz7AaNdUHfTwaKqimPR06Kdv65hKmFuA5p/GuRdSYfYASvXYYrPjqKkst1FP6sWjJtpXvZIT/06RXDbGXZ6LB3TFHpOahPy8ID746OyBKgWzOB3ZCNmFCk= - file_glob: true - file: build/release/* - skip_cleanup: true - on: - tags: true - all_branches: true - - stage: release - env: Facebook_Utils - install: - - bundle config set path 'vendor/bundle' - - travis_wait bundle install - script: - - bundle exec rake test:facebook_utils:ios - after_script: - - bash <(curl -s https://codecov.io/bash) - - stage: release - env: Twitter_Utils - install: - - bundle config set path 'vendor/bundle' - - travis_wait bundle install - script: - - bundle exec rake test:twitter_utils:ios - after_script: - - bash <(curl -s https://codecov.io/bash) - - stage: release - env: ParseUI - install: - - bundle config set path 'vendor/bundle' - - travis_wait bundle install - script: - - bundle exec rake test:parseui:all - after_script: - - bash <(curl -s https://codecov.io/bash) - - stage: release - env: Cocoapods - install: - - bundle config set path 'vendor/bundle' - - travis_wait bundle install - script: - - bundle exec pod setup - - travis_wait bundle exec pod lib lint --allow-warnings - deploy: - - provider: script - skip_cleanup: true - script: travis_wait bundle exec pod trunk push Parse.podspec --allow-warnings - on: - tags: true - all_branches: true - - stage: release - env: Docs - install: - - bundle config set path 'vendor/bundle' - - travis_wait bundle install - script: - - ./Scripts/jazzy.sh - deploy: - - provider: pages - skip_cleanup: true - github_token: $GITHUB_TOKEN - local_dir: ./docs/ - on: - all_branches: true - tags: true diff --git a/Carthage/Checkouts/facebook-objc-sdk b/Carthage/Checkouts/facebook-objc-sdk index 9398d3008..cdb8c71fb 160000 --- a/Carthage/Checkouts/facebook-objc-sdk +++ b/Carthage/Checkouts/facebook-objc-sdk @@ -1 +1 @@ -Subproject commit 9398d30089c2c14e0f0026e24388ca0829f8f1c5 +Subproject commit cdb8c71fb7f22b4f1af05c21246c12c1aa49f89e diff --git a/Parse/Parse.xcodeproj/project.pbxproj b/Parse/Parse.xcodeproj/project.pbxproj index 62bbf479b..67d68b77d 100644 --- a/Parse/Parse.xcodeproj/project.pbxproj +++ b/Parse/Parse.xcodeproj/project.pbxproj @@ -2509,6 +2509,7 @@ 81F0E89D19E6F83E00812A88 /* PFSubclassing.h in Headers */ = {isa = PBXBuildFile; fileRef = E9E81E8316EEF93E001D034F /* PFSubclassing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 91115EF91A097AF30092D1C9 /* PFEventuallyPin.h in Headers */ = {isa = PBXBuildFile; fileRef = 91115EF71A097AF30092D1C9 /* PFEventuallyPin.h */; settings = {ATTRIBUTES = (Private, ); }; }; 91115EFA1A097AF30092D1C9 /* PFEventuallyPin.m in Sources */ = {isa = PBXBuildFile; fileRef = 91115EF81A097AF30092D1C9 /* PFEventuallyPin.m */; }; + 916786CC258CEE8000BB5B4E /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A13518420281768000F5FD5 /* Bolts.framework */; }; 91CDB94C1A32E5C900FF830F /* PFEventuallyQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 91DF24911A09BA7600CFC7D4 /* PFEventuallyQueue.m */; }; 91CDB94D1A32E5C900FF830F /* PFPinningEventuallyQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 91DF24951A09BAF100CFC7D4 /* PFPinningEventuallyQueue.m */; }; 91CDB94E1A32E5E800FF830F /* PFEventuallyPin.m in Sources */ = {isa = PBXBuildFile; fileRef = 91115EF81A097AF30092D1C9 /* PFEventuallyPin.m */; }; @@ -2869,13 +2870,6 @@ remoteGlobalIDString = F5AFC9EA1BA752750076E927; remoteInfo = "Bolts-tvOS"; }; - 4A1351FA2028194C000F5FD5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4A1351082027FCFB000F5FD5 /* Bolts.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 81ED94111BE147CF00795F05; - remoteInfo = "Bolts-iOS"; - }; 4AA8ABFE20CEFC9A009306DD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4A1351082027FCFB000F5FD5 /* Bolts.xcodeproj */; @@ -3653,6 +3647,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 916786CC258CEE8000BB5B4E /* Bolts.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6919,7 +6914,6 @@ buildRules = ( ); dependencies = ( - 4A1351FB2028194C000F5FD5 /* PBXTargetDependency */, ); name = "Parse-iOS"; productName = "Parse-iOS"; @@ -8742,11 +8736,6 @@ name = "Bolts-tvOS"; targetProxy = 4A1351F62028193F000F5FD5 /* PBXContainerItemProxy */; }; - 4A1351FB2028194C000F5FD5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "Bolts-iOS"; - targetProxy = 4A1351FA2028194C000F5FD5 /* PBXContainerItemProxy */; - }; 4AA8ABFF20CEFC9A009306DD /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "Bolts-watchOS-Dynamic"; diff --git a/Parse/Parse.xcodeproj/xcshareddata/xcschemes/Parse-iOS.xcscheme b/Parse/Parse.xcodeproj/xcshareddata/xcschemes/Parse-iOS.xcscheme index 562310add..826b86486 100644 --- a/Parse/Parse.xcodeproj/xcshareddata/xcschemes/Parse-iOS.xcscheme +++ b/Parse/Parse.xcodeproj/xcshareddata/xcschemes/Parse-iOS.xcscheme @@ -81,6 +81,9 @@ + + diff --git a/Parse/Tests/Unit/ExtensionDataSharingMobileTests.m b/Parse/Tests/Unit/ExtensionDataSharingMobileTests.m index 8d68055ef..05c5a96b7 100644 --- a/Parse/Tests/Unit/ExtensionDataSharingMobileTests.m +++ b/Parse/Tests/Unit/ExtensionDataSharingMobileTests.m @@ -60,13 +60,16 @@ - (void)tearDown { - (void)testEnablingDataSharingWithoutAppGroupContainer { _testHelper.swizzledGroupContainerDirectoryPath = NO; - - XCTAssertThrows([Parse enableDataSharingWithApplicationGroupIdentifier:@"yolo"]); - - _testHelper.runningInExtensionEnvironment = YES; - + + [Parse enableDataSharingWithApplicationGroupIdentifier:@"yolo"]; XCTAssertThrows([Parse enableDataSharingWithApplicationGroupIdentifier:@"yolo" containingApplication:@"parentYolo"]); + + _testHelper.runningInExtensionEnvironment = YES; + XCTAssertThrows([Parse enableDataSharingWithApplicationGroupIdentifier:@"yolo"]); + [Parse enableDataSharingWithApplicationGroupIdentifier:@"yolo" + containingApplication:@"parentYolo"]; + } @end diff --git a/Parse/Tests/Unit/ExtensionDataSharingTests.m b/Parse/Tests/Unit/ExtensionDataSharingTests.m index 963301089..7a319dd36 100644 --- a/Parse/Tests/Unit/ExtensionDataSharingTests.m +++ b/Parse/Tests/Unit/ExtensionDataSharingTests.m @@ -129,7 +129,12 @@ - (void)testMigratingDataFromMainSandbox { PFObject *object = [PFObject objectWithClassName:@"TestObject"]; object[@"yolo"] = @"yarr"; - XCTAssertTrue([object pin]); + XCTestExpectation *expectation = [self currentSelectorTestExpectation]; + [object pinInBackgroundWithBlock:^(BOOL succeeded, NSError * _Nullable error) { + XCTAssertTrue(succeeded); + [expectation fulfill]; + }]; + [self waitForTestExpectations]; // We are using the same directory on OSX, so this check is irrelevant #if TARGET_OS_IPHONE @@ -173,7 +178,12 @@ - (void)testMigratingDataFromExtensionsSandbox { PFObject *object = [PFObject objectWithClassName:@"TestObject"]; object[@"yolo"] = @"yarr"; - XCTAssertTrue([object pin]); + XCTestExpectation *expectation = [self currentSelectorTestExpectation]; + [object pinInBackgroundWithBlock:^(BOOL succeeded, NSError * _Nullable error) { + XCTAssertTrue(succeeded); + [expectation fulfill]; + }]; + [self waitForTestExpectations]; // We are using the same directory on OSX, so this check is irrelevant #if TARGET_OS_IPHONE diff --git a/Parse/Tests/Unit/ParseClientConfigurationTests.m b/Parse/Tests/Unit/ParseClientConfigurationTests.m index fe9263bd8..a76d7d8be 100644 --- a/Parse/Tests/Unit/ParseClientConfigurationTests.m +++ b/Parse/Tests/Unit/ParseClientConfigurationTests.m @@ -117,9 +117,8 @@ - (void)testCopy { - (void)testExtensionDataSharing { ParseClientConfiguration *configuration = [ParseClientConfiguration emptyConfiguration]; - + #if !PF_TARGET_OS_OSX - // Innaccessible bundle identifiers should throw XCTAssertThrows(configuration.applicationGroupIdentifier = @"someBundleIdentifier"); #endif diff --git a/ParseUI/ParseUI.xcodeproj/project.pbxproj b/ParseUI/ParseUI.xcodeproj/project.pbxproj index d14d34fde..e5dadbe9a 100644 --- a/ParseUI/ParseUI.xcodeproj/project.pbxproj +++ b/ParseUI/ParseUI.xcodeproj/project.pbxproj @@ -62,12 +62,9 @@ 4A0ECC1D200D8C0200BA84A3 /* PFRect.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A9A9442200D0226005D8F4B /* PFRect.h */; }; 4A0ECC1E200D8C0200BA84A3 /* ParseUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A9A947C200D0226005D8F4B /* ParseUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4A0ECC1F200D8C0200BA84A3 /* PFActivityIndicatorTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A9A943A200D0226005D8F4B /* PFActivityIndicatorTableViewCell.h */; }; - 4A0ECC72200D992600BA84A3 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A941E200D01F1005D8F4B /* Bolts.framework */; }; - 4A0ECCAE200DA7F300BA84A3 /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A9497200D0329005D8F4B /* ParseUI.framework */; }; 4A0ECCB2200DA92700BA84A3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A0ECC73200D993000BA84A3 /* UIKit.framework */; }; 4A1350D12027F6AB000F5FD5 /* Parse.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E45B2027DC000066DE1A /* Parse.framework */; }; 4A1350D22027F6AB000F5FD5 /* ParseFacebookUtilsV4.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E43A2027CC330066DE1A /* ParseFacebookUtilsV4.framework */; }; - 4A1350D32027F6AB000F5FD5 /* ParseTwitterUtils.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E4272027CC2D0066DE1A /* ParseTwitterUtils.framework */; }; 4A1351E1202818EF000F5FD5 /* FBSDKLoginKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A1351DF202818EE000F5FD5 /* FBSDKLoginKit.framework */; }; 4A1351E2202818EF000F5FD5 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A1351E0202818EE000F5FD5 /* FBSDKCoreKit.framework */; }; 4A9A94A0200D03AA005D8F4B /* PFResources.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A9A9424200D0226005D8F4B /* PFResources.m */; }; @@ -134,6 +131,7 @@ 4A9A94F4200D1248005D8F4B /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A94E8200D05AA005D8F4B /* Social.framework */; }; 4A9A94F5200D1252005D8F4B /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A94E6200D05A5005D8F4B /* SystemConfiguration.framework */; }; 4A9A94F7200D125A005D8F4B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A94F6200D125A005D8F4B /* AudioToolbox.framework */; }; + 701070F6258D75DD00187034 /* ParseTwitterUtils.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E4272027CC2D0066DE1A /* ParseTwitterUtils.framework */; }; 8129E5F51A9CB067006752BC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 81472FA71A1AB37500FD6EED /* Images.xcassets */; }; 8129E5F71A9CB067006752BC /* 0.png in Resources */ = {isa = PBXBuildFile; fileRef = 81472FA91A1AB37500FD6EED /* 0.png */; }; 8129E5F81A9CB067006752BC /* 1.png in Resources */ = {isa = PBXBuildFile; fileRef = 81472FAA1A1AB37500FD6EED /* 1.png */; }; @@ -184,9 +182,7 @@ B9DDA283243C322D0003061D /* ParseTwitterUtils.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E4272027CC2D0066DE1A /* ParseTwitterUtils.framework */; }; B9DDA284243C32E50003061D /* ParseFacebookUtilsV4.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A51E4362027CC330066DE1A /* ParseFacebookUtilsV4.framework */; }; BC0632E023ABCC8F0089096D /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC0632DC23ABCB1D0089096D /* AuthenticationServices.framework */; }; - BC0632EA23AD3F050089096D /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A13523820282059000F5FD5 /* Bolts.framework */; }; BC488EA0246B196800947E3C /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC488E9F246B196800947E3C /* ParseUI.framework */; }; - BC488EA1246B196800947E3C /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC488E9F246B196800947E3C /* ParseUI.framework */; }; BC488EA2246B196800947E3C /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC488E9F246B196800947E3C /* ParseUI.framework */; }; BC8C2923246B1873000AEE3F /* ParseUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9A9497200D0329005D8F4B /* ParseUI.framework */; }; BCA5CC8523BFCFB8003BC0A0 /* SignInWithAppleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BCCBE8CB23BFB89D0044A79C /* SignInWithAppleTests.m */; }; @@ -263,20 +259,6 @@ remoteGlobalIDString = 81ECACB71D1E14E000FA7673; remoteInfo = "ParseTwitterUtils-iOS-Dynamic"; }; - 4A1350D62027F846000F5FD5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4A51E42C2027CC330066DE1A /* ParseFacebookUtils.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = D2AAC07D0554694100DB518D; - remoteInfo = "ParseFacebookUtilsV4-iOS"; - }; - 4A1350D82027F846000F5FD5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4A51E41D2027CC2D0066DE1A /* ParseTwitterUtils.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = D2AAC07D0554694100DB518D; - remoteInfo = "ParseTwitterUtils-iOS"; - }; 4A51E4242027CC2D0066DE1A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4A51E41D2027CC2D0066DE1A /* ParseTwitterUtils.xcodeproj */; @@ -452,13 +434,6 @@ remoteGlobalIDString = 81472F661A1AB33800FD6EED; remoteInfo = ParseUIDemo; }; - BCDB91EE246B199D0086532F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4A51E44B2027DC000066DE1A /* Parse.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 81C3821B19CCA89E0066284A; - remoteInfo = "Parse-iOS"; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -676,18 +651,15 @@ files = ( 4A1351E2202818EF000F5FD5 /* FBSDKCoreKit.framework in Frameworks */, BC8C2923246B1873000AEE3F /* ParseUI.framework in Frameworks */, - BC488EA1246B196800947E3C /* ParseUI.framework in Frameworks */, 4A1350D12027F6AB000F5FD5 /* Parse.framework in Frameworks */, 4A1350D22027F6AB000F5FD5 /* ParseFacebookUtilsV4.framework in Frameworks */, - 4A1350D32027F6AB000F5FD5 /* ParseTwitterUtils.framework in Frameworks */, + 701070F6258D75DD00187034 /* ParseTwitterUtils.framework in Frameworks */, 4A0ECCB2200DA92700BA84A3 /* UIKit.framework in Frameworks */, 4A9A94F7200D125A005D8F4B /* AudioToolbox.framework in Frameworks */, - BC0632EA23AD3F050089096D /* Bolts.framework in Frameworks */, 4A9A94F5200D1252005D8F4B /* SystemConfiguration.framework in Frameworks */, 4A9A94F4200D1248005D8F4B /* Social.framework in Frameworks */, 4A1351E1202818EF000F5FD5 /* FBSDKLoginKit.framework in Frameworks */, 4A9A94F3200D1241005D8F4B /* libsqlite3.tbd in Frameworks */, - 4A0ECC72200D992600BA84A3 /* Bolts.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -695,7 +667,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4A0ECCAE200DA7F300BA84A3 /* ParseUI.framework in Frameworks */, 4A9A94E9200D05AA005D8F4B /* Social.framework in Frameworks */, 4A9A94E7200D05A5005D8F4B /* SystemConfiguration.framework in Frameworks */, 4A9A94E5200D0598005D8F4B /* libsqlite3.tbd in Frameworks */, @@ -1487,9 +1458,6 @@ buildRules = ( ); dependencies = ( - BCDB91EF246B199D0086532F /* PBXTargetDependency */, - 4A1350D72027F846000F5FD5 /* PBXTargetDependency */, - 4A1350D92027F846000F5FD5 /* PBXTargetDependency */, 4A0ECCAD200DA7D100BA84A3 /* PBXTargetDependency */, ); name = ParseUIDemo; @@ -1802,7 +1770,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ ! -d $SRCROOT/Vendor ]; then\nmkdir $SRCROOT/Vendor\nfi\n\ncd $SRCROOT/Vendor\n\nif [[ ! -d \"FBSDKCoreKit.framework\" || ! -d \"FBSDKLoginKit.framework\" ]]; then\nARCHIVE_NAME=FBSDK.zip\n\nARCHIVE_URL=\"https://origincache.facebook.com/developers/resources/?id=facebook-ios-sdk-current.zip\"\ncurl $ARCHIVE_URL -o $ARCHIVE_NAME\n\nunzip $ARCHIVE_NAME -d fbsdk\nmv fbsdk/FBSDKCoreKit.framework .\nmv fbsdk/FBSDKLoginKit.framework .\n\nrm $ARCHIVE_NAME\nrm -r fbsdk\nfi\n"; + shellScript = "if [ ! -d $SRCROOT/Vendor ]; then\nmkdir $SRCROOT/Vendor\nfi\n\ncd $SRCROOT/Vendor\n\nif [[ ! -d \"FBSDKCoreKit.framework\" || ! -d \"FBSDKLoginKit.framework\" ]]; then\nARCHIVE_NAME=FBSDK.zip\n\nARCHIVE_URL=\"https://github.com/facebook/facebook-objc-sdk/releases/latest/download/FacebookSDK_Static.zip\"\ncurl -L $ARCHIVE_URL -o $ARCHIVE_NAME\n\nunzip $ARCHIVE_NAME -d fbsdk\nmv fbsdk/FBSDKCoreKit.framework .\nmv fbsdk/FBSDKLoginKit.framework .\n\nrm $ARCHIVE_NAME\nrm -r fbsdk\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -1977,16 +1945,6 @@ name = "ParseTwitterUtils-iOS-Dynamic"; targetProxy = 4A1350CE2027F683000F5FD5 /* PBXContainerItemProxy */; }; - 4A1350D72027F846000F5FD5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "ParseFacebookUtilsV4-iOS"; - targetProxy = 4A1350D62027F846000F5FD5 /* PBXContainerItemProxy */; - }; - 4A1350D92027F846000F5FD5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "ParseTwitterUtils-iOS"; - targetProxy = 4A1350D82027F846000F5FD5 /* PBXContainerItemProxy */; - }; 4A51E4422027CC3F0066DE1A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "ParseFacebookUtilsV4-iOS-Dynamic"; @@ -2012,11 +1970,6 @@ target = 81472F661A1AB33800FD6EED /* ParseUIDemo */; targetProxy = BCCBE8D723BFB9EB0044A79C /* PBXContainerItemProxy */; }; - BCDB91EF246B199D0086532F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "Parse-iOS"; - targetProxy = BCDB91EE246B199D0086532F /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -2070,6 +2023,11 @@ GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = ( + "$(value)", + "$(SANITIZE_FLAGS)", + "-Wl,-undefined,dynamic_lookup", + ); SDKROOT = iphoneos; }; name = Debug; diff --git a/ParseUI/ParseUIDemo/Swift/AppDelegate.swift b/ParseUI/ParseUIDemo/Swift/AppDelegate.swift index 0f1f2a678..d49e58ab4 100644 --- a/ParseUI/ParseUIDemo/Swift/AppDelegate.swift +++ b/ParseUI/ParseUIDemo/Swift/AppDelegate.swift @@ -31,7 +31,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // MARK: UIApplicationDelegate - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { Parse.setApplicationId("UdNpOP2XFoEiXLZEBDl6xONmCMH8VjETmnEsl0xJ", clientKey: "wNJFho0fQaQFQ2Fe1x9b67lVBakJiAtFj1Uz30A9") PFFacebookUtils.initializeFacebook(applicationLaunchOptions: launchOptions) PFTwitterUtils.initialize(withConsumerKey: "3Q9hMEKqqSg4ie2pibZ2sVJuv", consumerSecret: "IEZ9wv2d1EpXNGFKGp7sAGdxRtyqtPwygyciFZwTHTGhPp4FMj") @@ -47,7 +47,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { - return FBSDKApplicationDelegate.sharedInstance().application(application, open:url, sourceApplication: sourceApplication, annotation: annotation) + return ApplicationDelegate.shared.application(application, open:url, sourceApplication: sourceApplication, annotation: annotation) } // MARK: Test Data diff --git a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/DeletionCollectionViewController.swift b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/DeletionCollectionViewController.swift index 57e34ec44..1ca7d36f8 100644 --- a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/DeletionCollectionViewController.swift +++ b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/DeletionCollectionViewController.swift @@ -16,13 +16,17 @@ import Bolts.BFTask class DeletionCollectionViewController: PFQueryCollectionViewController, UIAlertViewDelegate { convenience init(className: String?) { let layout = UICollectionViewFlowLayout() - layout.sectionInset = UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0) + layout.sectionInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0) layout.minimumInteritemSpacing = 5.0 self.init(collectionViewLayout: layout, className: className) title = "Deletion Collection" - pullToRefreshEnabled = true + if #available(iOS 10.0, *) { + pullToRefreshEnabled = true + } else { + // Fallback on earlier versions + } objectsPerPage = 10 paginationEnabled = true @@ -38,7 +42,7 @@ class DeletionCollectionViewController: PFQueryCollectionViewController, UIAlert super.viewWillLayoutSubviews() if let layout = collectionViewLayout as? UICollectionViewFlowLayout { - let bounds = UIEdgeInsetsInsetRect(view.bounds, layout.sectionInset) + let bounds = view.bounds.inset(by: layout.sectionInset) let sideLength = min(bounds.width, bounds.height) / 2.0 - layout.minimumInteritemSpacing layout.itemSize = CGSize(width: sideLength, height: sideLength) } @@ -72,7 +76,7 @@ class DeletionCollectionViewController: PFQueryCollectionViewController, UIAlert alertDialog.addAction(UIAlertAction(title: "Save", style: .default) { action in if let title = titleTextField?.text { let object = PFObject(className: self.parseClassName!, dictionary: [ "title": title ]) - object.saveEventually().continueOnSuccessWith { _ -> AnyObject! in + object.saveEventually().continueOnSuccessWith { _ -> AnyObject in return self.loadObjects() } } @@ -128,7 +132,7 @@ class DeletionCollectionViewController: PFQueryCollectionViewController, UIAlert dictionary: [ "title": title ] ) - object.saveEventually().continueOnSuccessWith { _ -> AnyObject! in + object.saveEventually().continueOnSuccessWith { _ -> AnyObject in return self.loadObjects() } } diff --git a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/PaginatedCollectionViewController.swift b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/PaginatedCollectionViewController.swift index 2353d9267..7fbba76bc 100644 --- a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/PaginatedCollectionViewController.swift +++ b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/PaginatedCollectionViewController.swift @@ -30,12 +30,16 @@ class PaginatedCollectionViewController: PFQueryCollectionViewController { convenience init(className: String?) { let layout = UICollectionViewFlowLayout() - layout.sectionInset = UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0) + layout.sectionInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0) layout.minimumInteritemSpacing = 5.0 self.init(collectionViewLayout: layout, className: className) title = "Paginated Collection" - pullToRefreshEnabled = true + if #available(iOS 10.0, *) { + pullToRefreshEnabled = true + } else { + // Fallback on earlier versions + } objectsPerPage = 10 paginationEnabled = true } @@ -46,7 +50,7 @@ class PaginatedCollectionViewController: PFQueryCollectionViewController { super.viewWillLayoutSubviews() if let layout = collectionViewLayout as? UICollectionViewFlowLayout { - let bounds = UIEdgeInsetsInsetRect(view.bounds, layout.sectionInset) + let bounds = view.bounds.inset(by: layout.sectionInset) let sideLength = min(bounds.width, bounds.height) / 2.0 - layout.minimumInteritemSpacing layout.itemSize = CGSize(width: sideLength, height: sideLength) } @@ -67,7 +71,7 @@ class PaginatedCollectionViewController: PFQueryCollectionViewController { if let title = object?["title"] as? String { let attributedTitle = NSMutableAttributedString(string: title) if let priority = object?["priority"] as? Int { - let attributes = [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 13.0), NSAttributedStringKey.foregroundColor : UIColor.gray] + let attributes = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 13.0), NSAttributedString.Key.foregroundColor : UIColor.gray] let string = NSAttributedString(string: "\nPriority: \(priority)", attributes: attributes) attributedTitle.append(string) } diff --git a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SectionedCollectionViewController.swift b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SectionedCollectionViewController.swift index 4099162ea..2bc3000c4 100644 --- a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SectionedCollectionViewController.swift +++ b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SectionedCollectionViewController.swift @@ -57,12 +57,16 @@ class SectionedCollectionViewController: PFQueryCollectionViewController { convenience init(className: String?) { let layout = UICollectionViewFlowLayout() - layout.sectionInset = UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0) + layout.sectionInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0) layout.minimumInteritemSpacing = 5.0 self.init(collectionViewLayout: layout, className: className) title = "Sectioned Collection" - pullToRefreshEnabled = true + if #available(iOS 10.0, *) { + pullToRefreshEnabled = true + } else { + // Fallback on earlier versions + } } // MARK: UIViewController @@ -70,14 +74,14 @@ class SectionedCollectionViewController: PFQueryCollectionViewController { override func viewDidLoad() { super.viewDidLoad() - collectionView?.register(SimpleCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header") + collectionView?.register(SimpleCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "header") } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() if let layout = collectionViewLayout as? UICollectionViewFlowLayout { - let bounds = UIEdgeInsetsInsetRect(view.bounds, layout.sectionInset) + let bounds = view.bounds.inset(by: layout.sectionInset) let sideLength = min(bounds.width, bounds.height) / 2.0 - layout.minimumInteritemSpacing layout.itemSize = CGSize(width: sideLength, height: sideLength) } @@ -135,7 +139,7 @@ extension SectionedCollectionViewController { } override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { - if kind == UICollectionElementKindSectionHeader, + if kind == UICollectionView.elementKindSectionHeader, let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath) as? SimpleCollectionReusableView { view.label.text = "Priority \(sectionKeys[indexPath.section])" return view diff --git a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SimpleCollectionViewController.swift b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SimpleCollectionViewController.swift index c9a0f791b..a713cf647 100644 --- a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SimpleCollectionViewController.swift +++ b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SimpleCollectionViewController.swift @@ -30,12 +30,16 @@ class SimpleCollectionViewController: PFQueryCollectionViewController { convenience init(className: String?) { let layout = UICollectionViewFlowLayout() - layout.sectionInset = UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0) + layout.sectionInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0) layout.minimumInteritemSpacing = 5.0 self.init(collectionViewLayout: layout, className: className) title = "Simple Collection" - pullToRefreshEnabled = true + if #available(iOS 10.0, *) { + pullToRefreshEnabled = true + } else { + // Fallback on earlier versions + } paginationEnabled = false } @@ -45,7 +49,7 @@ class SimpleCollectionViewController: PFQueryCollectionViewController { super.viewWillLayoutSubviews() if let layout = collectionViewLayout as? UICollectionViewFlowLayout { - let bounds = UIEdgeInsetsInsetRect(view.bounds, layout.sectionInset) + let bounds = view.bounds.inset(by: layout.sectionInset) let sideLength = min(bounds.width, bounds.height) / 2.0 - layout.minimumInteritemSpacing layout.itemSize = CGSize(width: sideLength, height: sideLength) } @@ -66,7 +70,7 @@ class SimpleCollectionViewController: PFQueryCollectionViewController { if let title = object?["title"] as? String { let attributedTitle = NSMutableAttributedString(string: title) if let priority = object?["priority"] as? Int { - let attributes = [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 13.0), NSAttributedStringKey.foregroundColor : UIColor.gray] + let attributes = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 13.0), NSAttributedString.Key.foregroundColor : UIColor.gray] let string = NSAttributedString(string: "\nPriority: \(priority)", attributes: attributes) attributedTitle.append(string) } diff --git a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/StoryboardCollectionViewController.swift b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/StoryboardCollectionViewController.swift index f339e4f9c..87d139e7e 100644 --- a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/StoryboardCollectionViewController.swift +++ b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/StoryboardCollectionViewController.swift @@ -32,7 +32,7 @@ class StoryboardCollectionViewController: PFQueryCollectionViewController { super.viewDidLoad() if let layout = collectionViewLayout as? UICollectionViewFlowLayout { - layout.sectionInset = UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0) + layout.sectionInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0) layout.minimumInteritemSpacing = 5.0 } } @@ -41,7 +41,7 @@ class StoryboardCollectionViewController: PFQueryCollectionViewController { super.viewWillLayoutSubviews() if let layout = collectionViewLayout as? UICollectionViewFlowLayout { - let bounds = UIEdgeInsetsInsetRect(view.bounds, layout.sectionInset) + let bounds = view.bounds.inset(by: layout.sectionInset) let sideLength = min(bounds.width, bounds.height) / 2.0 - layout.minimumInteritemSpacing layout.itemSize = CGSize(width: sideLength, height: sideLength) } @@ -62,7 +62,7 @@ class StoryboardCollectionViewController: PFQueryCollectionViewController { if let title = object?["title"] as? String { let attributedTitle = NSMutableAttributedString(string: title) if let priority = object?["priority"] as? Int { - let attributes = [NSAttributedStringKey.font : UIFont.systemFont(ofSize: 13.0), NSAttributedStringKey.foregroundColor : UIColor.gray] + let attributes = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 13.0), NSAttributedString.Key.foregroundColor : UIColor.gray] let string = NSAttributedString(string: "\nPriority: \(priority)", attributes: attributes) attributedTitle.append(string) } diff --git a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SubtitleImageCollectionViewController.swift b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SubtitleImageCollectionViewController.swift index 48ce6bb26..90daf8079 100644 --- a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SubtitleImageCollectionViewController.swift +++ b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryCollectionViewController/SubtitleImageCollectionViewController.swift @@ -30,12 +30,16 @@ class SubtitleImageCollectionViewController: PFQueryCollectionViewController { convenience init(className: String?) { let layout = UICollectionViewFlowLayout() - layout.sectionInset = UIEdgeInsetsMake(0.0, 10.0, 0.0, 10.0) + layout.sectionInset = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0) layout.minimumInteritemSpacing = 5.0 self.init(collectionViewLayout: layout, className: className) title = "Image Collection" - pullToRefreshEnabled = true + if #available(iOS 10.0, *) { + pullToRefreshEnabled = true + } else { + // Fallback on earlier versions + } paginationEnabled = false } @@ -45,7 +49,7 @@ class SubtitleImageCollectionViewController: PFQueryCollectionViewController { super.viewWillLayoutSubviews() if let layout = collectionViewLayout as? UICollectionViewFlowLayout { - let bounds = UIEdgeInsetsInsetRect(view.bounds, layout.sectionInset) + let bounds = view.bounds.inset(by: layout.sectionInset) let sideLength = min(bounds.width, bounds.height) / 2.0 - layout.minimumInteritemSpacing layout.itemSize = CGSize(width: sideLength, height: sideLength) } diff --git a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryTableViewController/DeletionTableViewController.swift b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryTableViewController/DeletionTableViewController.swift index b891a0fd0..e90022fe1 100644 --- a/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryTableViewController/DeletionTableViewController.swift +++ b/ParseUI/ParseUIDemo/Swift/CustomViewControllers/QueryTableViewController/DeletionTableViewController.swift @@ -50,7 +50,7 @@ class DeletionTableViewController: PFQueryTableViewController, UIAlertViewDelega } override func tableView(_ tableView: UITableView, - commit editingStyle: UITableViewCellEditingStyle, + commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if (editingStyle == .delete) { removeObject(at: indexPath) @@ -72,7 +72,7 @@ class DeletionTableViewController: PFQueryTableViewController, UIAlertViewDelega alertDialog.addAction(UIAlertAction(title: "Save", style: .default) { _ in if let title = titleTextField.text { let object = PFObject(className: self.parseClassName!, dictionary: [ "title": title ]) - object.saveInBackground().continueOnSuccessWith { _ -> AnyObject! in + object.saveInBackground().continueOnSuccessWith { _ -> AnyObject in return self.loadObjects() } } @@ -110,7 +110,7 @@ class DeletionTableViewController: PFQueryTableViewController, UIAlertViewDelega if let title = alertView.textField(at: 0)?.text { let object = PFObject(className: self.parseClassName!, dictionary: [ "title": title ]) - object.saveEventually().continueOnSuccessWith { _ -> AnyObject! in + object.saveEventually().continueOnSuccessWith { _ -> AnyObject in return self.loadObjects() } } diff --git a/README.md b/README.md index 086429ff0..d8cf05feb 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@

Carthage compatible Dependencies - Build status + CI status + Release status Build status Coverage status Join the conversation