diff --git a/.swift-version b/.swift-version deleted file mode 100644 index 9f55b2ccb..000000000 --- a/.swift-version +++ /dev/null @@ -1 +0,0 @@ -3.0 diff --git a/.travis.yml b/.travis.yml index 493b15d33..673eb12c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,13 @@ -osx_image: xcode8.1 +osx_image: xcode9.2 language: objective-c -cache: - - cocoapods - +cache: cocoapods podfile: Example/Podfile + before_install: - gem install cocoapods # Since Travis is not always on latest version - pod repo update - pod install --project-directory=Example script: -- set -o pipefail && xcodebuild test -workspace Example/Example.xcworkspace -scheme Example -destination 'platform=iOS Simulator,name=iPhone 6s,OS=10.1' | xcpretty -# - pod lib lint --allow-warnings \ No newline at end of file +- set -o pipefail && xcodebuild test -workspace Example/Example.xcworkspace -scheme Example -destination 'platform=iOS Simulator,name=iPhone 7,OS=11.2' | xcpretty +# - pod lib lint --allow-warnings diff --git a/CHANGELOG.md b/CHANGELOG.md index 72d3849d5..961f89a99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,74 @@ # Change Log +## [Unreleased](https://github.com/FolioReader/FolioReaderKit/tree/HEAD) + +[Full Changelog](https://github.com/FolioReader/FolioReaderKit/compare/1.3.0...HEAD) + +**Closed issues:** + +- Version 1.3.0 is not available in Cocoapods [\#311](https://github.com/FolioReader/FolioReaderKit/issues/311) + +## [1.3.0](https://github.com/FolioReader/FolioReaderKit/tree/1.3.0) (2018-02-12) +[Full Changelog](https://github.com/FolioReader/FolioReaderKit/compare/1.2.0...1.3.0) + +**Fixed bugs:** + +- shouldHideNavigationOnTap not working [\#268](https://github.com/FolioReader/FolioReaderKit/issues/268) +- Can't change UIWebView backgroundColor correctly when `paginationBreakingMode` is `.page` on night mode in iOS 10.3 [\#227](https://github.com/FolioReader/FolioReaderKit/issues/227) + +**Closed issues:** + +- Can't compile after updating to Xcode 9 - errors in dependencies? [\#298](https://github.com/FolioReader/FolioReaderKit/issues/298) +- Latest Realm Dependency [\#294](https://github.com/FolioReader/FolioReaderKit/issues/294) +- How to add FolioReader as a subview in my custom view [\#293](https://github.com/FolioReader/FolioReaderKit/issues/293) +- Not installed by Carthage [\#291](https://github.com/FolioReader/FolioReaderKit/issues/291) +- Pod installation not compatible with swift 3/4 [\#288](https://github.com/FolioReader/FolioReaderKit/issues/288) +- Problems when use it with Carthage [\#286](https://github.com/FolioReader/FolioReaderKit/issues/286) +- text to speech for other languages [\#285](https://github.com/FolioReader/FolioReaderKit/issues/285) +- Build failure? [\#280](https://github.com/FolioReader/FolioReaderKit/issues/280) +- Realm version update [\#278](https://github.com/FolioReader/FolioReaderKit/issues/278) +- Pod error [\#273](https://github.com/FolioReader/FolioReaderKit/issues/273) +- Layout Issue After Integrating in Swift 4 [\#271](https://github.com/FolioReader/FolioReaderKit/issues/271) +- Unable to start with iOS Folio Reader /Swift3/Xcode 9 [\#266](https://github.com/FolioReader/FolioReaderKit/issues/266) +- Will FolioReaderKit support Swift 4.0? [\#263](https://github.com/FolioReader/FolioReaderKit/issues/263) +- 'FolioReader' initializer is inaccessible due to 'fileprivate' protection level [\#262](https://github.com/FolioReader/FolioReaderKit/issues/262) +- Error building for iOS 10 with MenuItemKit [\#260](https://github.com/FolioReader/FolioReaderKit/issues/260) +- whose view is not in the window hierarchy [\#259](https://github.com/FolioReader/FolioReaderKit/issues/259) +- not supporting swift 3.1 [\#256](https://github.com/FolioReader/FolioReaderKit/issues/256) +- Laggy on ios 9.3 \(iPhone 6s Plus\) [\#254](https://github.com/FolioReader/FolioReaderKit/issues/254) +- SemiNightmode [\#253](https://github.com/FolioReader/FolioReaderKit/issues/253) +- How to build the example? [\#252](https://github.com/FolioReader/FolioReaderKit/issues/252) +- audio voices [\#251](https://github.com/FolioReader/FolioReaderKit/issues/251) +- Has FolioReaderKit support read file from path local ? [\#250](https://github.com/FolioReader/FolioReaderKit/issues/250) +- Perform direct action instead of showing UIMenuController? [\#249](https://github.com/FolioReader/FolioReaderKit/issues/249) +- How to change default Green color in Folio UI [\#248](https://github.com/FolioReader/FolioReaderKit/issues/248) +- Problem with missing declarations [\#247](https://github.com/FolioReader/FolioReaderKit/issues/247) +- Is there a way to read the epub file from URL instead of from local ? [\#246](https://github.com/FolioReader/FolioReaderKit/issues/246) +- Core text replace WebView [\#245](https://github.com/FolioReader/FolioReaderKit/issues/245) +- Hi man, do u have objective-c Version? :\) [\#244](https://github.com/FolioReader/FolioReaderKit/issues/244) +- Search Feature not found -- Feature Request [\#243](https://github.com/FolioReader/FolioReaderKit/issues/243) +- Could you please plan FolioReader for iOS written in Objective-C๏ผŸ [\#242](https://github.com/FolioReader/FolioReaderKit/issues/242) +- Why my NightMode cant change BGColor [\#231](https://github.com/FolioReader/FolioReaderKit/issues/231) +- epub responsive layout support [\#230](https://github.com/FolioReader/FolioReaderKit/issues/230) +- A white background at the bottom when set to horizontal scrolling [\#224](https://github.com/FolioReader/FolioReaderKit/issues/224) +- Access ePub metadata [\#182](https://github.com/FolioReader/FolioReaderKit/issues/182) + +**Merged pull requests:** + +- Update CocoaPods to version 1.4.0 [\#309](https://github.com/FolioReader/FolioReaderKit/pull/309) ([tschob](https://github.com/tschob)) +- Add custom unzip path setting to FolioReaderContainer [\#306](https://github.com/FolioReader/FolioReaderKit/pull/306) ([revolter](https://github.com/revolter)) +- Fix horizontal scroll direction not working [\#305](https://github.com/FolioReader/FolioReaderKit/pull/305) ([revolter](https://github.com/revolter)) +- Remove superfluous optional wrapping from metadata getters [\#304](https://github.com/FolioReader/FolioReaderKit/pull/304) ([revolter](https://github.com/revolter)) +- Add unzip path to title and author name getters [\#303](https://github.com/FolioReader/FolioReaderKit/pull/303) ([revolter](https://github.com/revolter)) +- Fixed issue \#268 showing/hiding navigation on tap in iOS 11. [\#301](https://github.com/FolioReader/FolioReaderKit/pull/301) ([ryan-w](https://github.com/ryan-w)) +- Fixed logic issue when checking if ePub shoud be unzipped. [\#300](https://github.com/FolioReader/FolioReaderKit/pull/300) ([ryan-w](https://github.com/ryan-w)) +- Removing forced unwrapping [\#297](https://github.com/FolioReader/FolioReaderKit/pull/297) ([rodrigorsa](https://github.com/rodrigorsa)) +- Replaced `func` with `var` on FRbook [\#296](https://github.com/FolioReader/FolioReaderKit/pull/296) ([rodrigorsa](https://github.com/rodrigorsa)) +- Swift 4, iPhone X support and Carthage fixes [\#287](https://github.com/FolioReader/FolioReaderKit/pull/287) ([prsolucoes](https://github.com/prsolucoes)) +- Feature/epub title in navbar [\#281](https://github.com/FolioReader/FolioReaderKit/pull/281) ([noxsicarius](https://github.com/noxsicarius)) +- Update realm to 3.0.2 [\#279](https://github.com/FolioReader/FolioReaderKit/pull/279) ([noxsicarius](https://github.com/noxsicarius)) +- update Podfile.lock [\#277](https://github.com/FolioReader/FolioReaderKit/pull/277) ([EmersonCarpes](https://github.com/EmersonCarpes)) + ## [1.2.0](https://github.com/FolioReader/FolioReaderKit/tree/1.2.0) (2017-05-31) [Full Changelog](https://github.com/FolioReader/FolioReaderKit/compare/1.1.0...1.2.0) @@ -72,7 +141,7 @@ - Fixed code style [\#191](https://github.com/FolioReader/FolioReaderKit/pull/191) ([revolter](https://github.com/revolter)) - Swift 3 syntax && Carthage hint [\#189](https://github.com/FolioReader/FolioReaderKit/pull/189) ([piechart](https://github.com/piechart)) - Add custom ePub unzip path option [\#181](https://github.com/FolioReader/FolioReaderKit/pull/181) ([revolter](https://github.com/revolter)) -- Add methods returning Epub's title and Author [\#179](https://github.com/FolioReader/FolioReaderKit/pull/179) ([Vandeth](https://github.com/Vandeth)) +- Add methods returning Epub's title and Author [\#179](https://github.com/FolioReader/FolioReaderKit/pull/179) ([Vandetho](https://github.com/Vandetho)) - Fix scroll direction being ignored on first run [\#178](https://github.com/FolioReader/FolioReaderKit/pull/178) ([revolter](https://github.com/revolter)) - Fix incorrect menu on second highlight attempt [\#177](https://github.com/FolioReader/FolioReaderKit/pull/177) ([revolter](https://github.com/revolter)) - Fix warnings about exceding UIColor range [\#176](https://github.com/FolioReader/FolioReaderKit/pull/176) ([revolter](https://github.com/revolter)) diff --git a/Cartfile b/Cartfile index 71583ba11..62b60a747 100644 --- a/Cartfile +++ b/Cartfile @@ -1,7 +1,7 @@ -github "ZipArchive/ZipArchive" ~> 1.6 -github "cxa/MenuItemKit" == 2.0 +github "ZipArchive/ZipArchive" == 2.1.1 +github "cxa/MenuItemKit" == 3.0.0 github "alexpopov/ZFDragableModalTransition" "merge-carthage-into-zoonooz" -github "tadija/AEXML" == 4.0 -github "ArtSabintsev/FontBlaster" == 3.0.0 -github "jessesquires/JSQWebViewController" ~> 5.0 -github "realm/realm-cocoa" ~> 3.0.2 +github "tadija/AEXML" == 4.2.2 +github "ArtSabintsev/FontBlaster" == 4.0.1 +github "jessesquires/JSQWebViewController" == 6.0.0 +github "realm/realm-cocoa" == 3.1.1 diff --git a/Cartfile.resolved b/Cartfile.resolved index 9a7404577..883b6f499 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,7 +1,7 @@ -github "tadija/AEXML" "4.0.0" -github "ArtSabintsev/FontBlaster" "3.0.0" -github "jessesquires/JSQWebViewController" "5.0.0" -github "cxa/MenuItemKit" "2.0" +github "ArtSabintsev/FontBlaster" "4.0.1" +github "ZipArchive/ZipArchive" "v2.1.1" github "alexpopov/ZFDragableModalTransition" "8da951efb4202385630d1cf7104b60d1208f807e" -github "ZipArchive/ZipArchive" "v1.8.1" -github "realm/realm-cocoa" "v3.0.2" +github "cxa/MenuItemKit" "3.0.0" +github "jessesquires/JSQWebViewController" "6.0.0" +github "realm/realm-cocoa" "v3.1.1" +github "tadija/AEXML" "4.2.2" diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index 717083b95..076595264 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -293,7 +293,6 @@ 1A42C2861C0E3882000F2137 /* Frameworks */, 1A42C2871C0E3882000F2137 /* Resources */, 4521900C899CED51BB10949C /* [CP] Embed Pods Frameworks */, - 9C061ADCCB0FC21E8DF4B220 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -313,7 +312,6 @@ 3AAA8B6C1E9BB78B00A47E5A /* Frameworks */, 3AAA8B6E1E9BB78B00A47E5A /* Resources */, 3AAA8B751E9BB78B00A47E5A /* [CP] Embed Pods Frameworks */, - 3AAA8B761E9BB78B00A47E5A /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -334,7 +332,6 @@ CA10C12E1C572A4B0049165D /* Frameworks */, CA10C12F1C572A4B0049165D /* Resources */, C1392FF51E4FD15EBB5AA8DD /* [CP] Embed Pods Frameworks */, - 652A7706A17894A2B0BA1503 /* [CP] Copy Pods Resources */, E82F486563C1547E0775A59F /* ๐Ÿ“ฆ Embed Pods Frameworks */, 064D38CE83FACC358B7C0EC8 /* ๐Ÿ“ฆ Copy Pods Resources */, ); @@ -357,7 +354,6 @@ D12066601D65FABD006E1D18 /* Frameworks */, D12066611D65FABD006E1D18 /* Resources */, ACD2A7368ACAFB17422DAA7F /* [CP] Embed Pods Frameworks */, - B26D5E41B862346EA808EDB9 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -375,7 +371,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = FolioReader; TargetAttributes = { 1A42C2881C0E3882000F2137 = { @@ -390,19 +386,19 @@ }; }; 3AAA8B671E9BB78B00A47E5A = { - DevelopmentTeam = 32F2T8EJ6G; + DevelopmentTeam = 99AHAA343Q; ProvisioningStyle = Automatic; }; CA10C1301C572A4B0049165D = { CreatedOnToolsVersion = 7.3; - DevelopmentTeam = 32F2T8EJ6G; + DevelopmentTeam = 99AHAA343Q; LastSwiftMigration = 0800; ProvisioningStyle = Automatic; TestTargetID = 1A42C2881C0E3882000F2137; }; D12066621D65FABD006E1D18 = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = 32F2T8EJ6G; + DevelopmentTeam = 99AHAA343Q; ProvisioningStyle = Automatic; }; }; @@ -481,13 +477,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-FolioReaderTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 064D38CE83FACC358B7C0EC8 /* ๐Ÿ“ฆ Copy Pods Resources */ = { @@ -526,13 +525,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Storyboard-Example-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 3AAA8B681E9BB78B00A47E5A /* [CP] Check Pods Manifest.lock */ = { @@ -541,13 +543,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-MultipleInstance-Example-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 3AAA8B751E9BB78B00A47E5A /* [CP] Embed Pods Frameworks */ = { @@ -556,114 +561,134 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-MultipleInstance-Example/Pods-MultipleInstance-Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/AEXML/AEXML.framework", + "${BUILT_PRODUCTS_DIR}/FolioReaderKit/FolioReaderKit.framework", + "${BUILT_PRODUCTS_DIR}/FontBlaster/FontBlaster.framework", + "${BUILT_PRODUCTS_DIR}/JSQWebViewController/JSQWebViewController.framework", + "${BUILT_PRODUCTS_DIR}/MenuItemKit/MenuItemKit.framework", + "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", + "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", + "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework", + "${BUILT_PRODUCTS_DIR}/ZFDragableModalTransition/ZFDragableModalTransition.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AEXML.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FolioReaderKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FontBlaster.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQWebViewController.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MenuItemKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZFDragableModalTransition.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MultipleInstance-Example/Pods-MultipleInstance-Example-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 3AAA8B761E9BB78B00A47E5A /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MultipleInstance-Example/Pods-MultipleInstance-Example-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; 4521900C899CED51BB10949C /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/AEXML/AEXML.framework", + "${BUILT_PRODUCTS_DIR}/FolioReaderKit/FolioReaderKit.framework", + "${BUILT_PRODUCTS_DIR}/FontBlaster/FontBlaster.framework", + "${BUILT_PRODUCTS_DIR}/JSQWebViewController/JSQWebViewController.framework", + "${BUILT_PRODUCTS_DIR}/MenuItemKit/MenuItemKit.framework", + "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", + "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", + "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework", + "${BUILT_PRODUCTS_DIR}/ZFDragableModalTransition/ZFDragableModalTransition.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AEXML.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FolioReaderKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FontBlaster.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQWebViewController.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MenuItemKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZFDragableModalTransition.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 652A7706A17894A2B0BA1503 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-FolioReaderTests/Pods-FolioReaderTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9C061ADCCB0FC21E8DF4B220 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; ACD2A7368ACAFB17422DAA7F /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-Storyboard-Example/Pods-Storyboard-Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/AEXML/AEXML.framework", + "${BUILT_PRODUCTS_DIR}/FolioReaderKit/FolioReaderKit.framework", + "${BUILT_PRODUCTS_DIR}/FontBlaster/FontBlaster.framework", + "${BUILT_PRODUCTS_DIR}/JSQWebViewController/JSQWebViewController.framework", + "${BUILT_PRODUCTS_DIR}/MenuItemKit/MenuItemKit.framework", + "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", + "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", + "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework", + "${BUILT_PRODUCTS_DIR}/ZFDragableModalTransition/ZFDragableModalTransition.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AEXML.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FolioReaderKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FontBlaster.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQWebViewController.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MenuItemKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZFDragableModalTransition.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Storyboard-Example/Pods-Storyboard-Example-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - B26D5E41B862346EA808EDB9 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Storyboard-Example/Pods-Storyboard-Example-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; C1392FF51E4FD15EBB5AA8DD /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-FolioReaderTests/Pods-FolioReaderTests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/AEXML/AEXML.framework", + "${BUILT_PRODUCTS_DIR}/FolioReaderKit/FolioReaderKit.framework", + "${BUILT_PRODUCTS_DIR}/FontBlaster/FontBlaster.framework", + "${BUILT_PRODUCTS_DIR}/JSQWebViewController/JSQWebViewController.framework", + "${BUILT_PRODUCTS_DIR}/MenuItemKit/MenuItemKit.framework", + "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", + "${BUILT_PRODUCTS_DIR}/RealmSwift/RealmSwift.framework", + "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework", + "${BUILT_PRODUCTS_DIR}/ZFDragableModalTransition/ZFDragableModalTransition.framework", + "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework", + "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AEXML.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FolioReaderKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FontBlaster.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/JSQWebViewController.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MenuItemKit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RealmSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ZFDragableModalTransition.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -691,13 +716,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Example-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -815,14 +843,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -850,6 +884,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -862,14 +897,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -890,6 +931,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -909,7 +951,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -927,7 +968,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 3.0; }; name = Release; }; @@ -939,15 +979,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = 99AHAA343Q; INFOPLIST_FILE = "MultipleInstances-Example/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.example.multipleinstances; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 2; }; name = Debug; @@ -960,13 +998,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = 99AHAA343Q; INFOPLIST_FILE = "MultipleInstances-Example/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.example.multipleinstances; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 2; }; name = Release; @@ -978,13 +1014,12 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUNDLE_LOADER = "$(TEST_HOST)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = 99AHAA343Q; INFOPLIST_FILE = FolioReaderTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; name = Debug; @@ -996,13 +1031,12 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUNDLE_LOADER = "$(TEST_HOST)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = 99AHAA343Q; INFOPLIST_FILE = FolioReaderTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; name = Release; @@ -1015,13 +1049,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = 99AHAA343Q; INFOPLIST_FILE = "Storyboard-Example/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.example.storyboard; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -1033,13 +1065,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = 99AHAA343Q; INFOPLIST_FILE = "Storyboard-Example/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.example.storyboard; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme index d78b6713e..b59c9f1de 100644 --- a/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme @@ -1,6 +1,6 @@ @@ -45,6 +46,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Example/Example.xcodeproj/xcshareddata/xcschemes/Storyboard-Example.xcscheme b/Example/Example.xcodeproj/xcshareddata/xcschemes/Storyboard-Example.xcscheme index 6e52ff0ee..307bc4f3b 100644 --- a/Example/Example.xcodeproj/xcshareddata/xcschemes/Storyboard-Example.xcscheme +++ b/Example/Example.xcodeproj/xcshareddata/xcschemes/Storyboard-Example.xcscheme @@ -1,6 +1,6 @@ @@ -45,6 +46,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Example/Example/ViewController.swift b/Example/Example/ViewController.swift index 0c41bb227..4e9a31728 100755 --- a/Example/Example/ViewController.swift +++ b/Example/Example/ViewController.swift @@ -75,13 +75,11 @@ class ViewController: UIViewController { } do { - if let image = try FolioReader.getCoverImage(bookPath) { - button?.setBackgroundImage(image, for: .normal) - } - } catch let e as FolioReaderError { - print(e.localizedDescription) + let image = try FolioReader.getCoverImage(bookPath) + + button?.setBackgroundImage(image, for: .normal) } catch { - print("Unkown error") + print(error.localizedDescription) } } } diff --git a/Example/FolioReaderTests/FolioReaderTests.swift b/Example/FolioReaderTests/FolioReaderTests.swift index d02cd74da..09243d3d4 100644 --- a/Example/FolioReaderTests/FolioReaderTests.swift +++ b/Example/FolioReaderTests/FolioReaderTests.swift @@ -15,26 +15,66 @@ class FolioReaderTests: QuickSpec { override func spec() { context("epub parsing") { var subject: FREpubParser! + var epubPath: String! beforeEach { guard let path = Bundle.main.path(forResource: "The Silver Chair", ofType: "epub") else { fail("Could not read the epub file") return } + subject = FREpubParser() + epubPath = path + do { - let book = try subject.readEpub(epubPath: path) - print(book!.tableOfContents.first!.title) - } catch let e as FolioReaderError { - print(e.localizedDescription) + let book = try subject.readEpub(epubPath: epubPath) + print(book.tableOfContents.first!.title) } catch { - print("Unknown error") + fail("Error: \(error.localizedDescription)") } } - it("correctly parses a properly formatted document") { + it("flat table of contents") { + expect(subject.flatTOC.count).to(equal(17)) + } + + it("parses table of contents") { expect(subject.book.tableOfContents.count).to(equal(17)) } + + it("parses cover image") { + guard let coverImage = subject.book.coverImage, let fromFileImage = UIImage(contentsOfFile: coverImage.fullHref) else { + fail("Could not read the cover image") + return + } + + do { + let parsedImage = try subject.parseCoverImage(epubPath) + let data1 = UIImagePNGRepresentation(parsedImage) + let data2 = UIImagePNGRepresentation(fromFileImage) + expect(data1).to(equal(data2)) + } catch { + fail("Error: \(error.localizedDescription)") + } + } + + it("parses book title") { + do { + let title = try subject.parseTitle(epubPath) + expect(title).to(equal("The Silver Chair")) + } catch { + fail("Error: \(error.localizedDescription)") + } + } + + it("parses author name") { + do { + let name = try subject.parseAuthorName(epubPath) + expect(name).to(equal("C. S. Lewis")) + } catch { + fail("Error: \(error.localizedDescription)") + } + } } } } diff --git a/Example/MultipleInstances-Example/CodeExample/CodeExampleViewController.swift b/Example/MultipleInstances-Example/CodeExample/CodeExampleViewController.swift index 1d27ed0d6..ca080bf6a 100755 --- a/Example/MultipleInstances-Example/CodeExample/CodeExampleViewController.swift +++ b/Example/MultipleInstances-Example/CodeExample/CodeExampleViewController.swift @@ -73,10 +73,8 @@ class CodeExampleViewController: UIViewController { if let image = try FolioReader.getCoverImage(bookPath) { button?.setBackgroundImage(image, for: .normal) } - } catch let e as FolioReaderError { - print(e.localizedDescription) } catch { - print("Unkown error") + print(error.localizedDescription) } } } diff --git a/Example/Podfile b/Example/Podfile index 11cc4a336..b16485040 100755 --- a/Example/Podfile +++ b/Example/Podfile @@ -8,8 +8,8 @@ def shared_pods end def testing_pods - pod 'Quick', '0.10.0' - pod 'Nimble', '~> 5.0.0' + pod 'Quick', '1.2.0' + pod 'Nimble', '7.0.2' end target 'Example' do diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 8ec540186..33f298757 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,46 +1,61 @@ PODS: - - AEXML (4.0.0) - - FolioReaderKit (1.2.0): - - AEXML (= 4.0) - - FontBlaster (= 3.0.0) - - JSQWebViewController (~> 5.0) - - MenuItemKit (= 2.0) - - RealmSwift (= 3.0.2) - - SSZipArchive (~> 1.8) - - ZFDragableModalTransition (~> 0.6) - - FontBlaster (3.0.0) - - JSQWebViewController (5.0.0) - - MenuItemKit (2.0) - - Realm (3.0.2): - - Realm/Headers (= 3.0.2) - - Realm/Headers (3.0.2) - - RealmSwift (3.0.2): - - Realm (= 3.0.2) - - SSZipArchive (1.8.1) + - AEXML (4.2.2) + - FolioReaderKit (1.3.0): + - AEXML (= 4.2.2) + - FontBlaster (= 4.0.1) + - JSQWebViewController (= 6.0.0) + - MenuItemKit (= 3.0.0) + - RealmSwift (= 3.1.1) + - SSZipArchive (= 2.1.1) + - ZFDragableModalTransition (= 0.6) + - FontBlaster (4.0.1) + - JSQWebViewController (6.0.0) + - MenuItemKit (3.0.0) + - Nimble (7.0.2) + - Quick (1.2.0) + - Realm (3.1.1): + - Realm/Headers (= 3.1.1) + - Realm/Headers (3.1.1) + - RealmSwift (3.1.1): + - Realm (= 3.1.1) + - SSZipArchive (2.1.1) - ZFDragableModalTransition (0.6) DEPENDENCIES: - FolioReaderKit (from `../`) - - Nimble (~> 5.0.0) - - Quick (= 0.10.0) + - Nimble (= 7.0.2) + - Quick (= 1.2.0) + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - AEXML + - FontBlaster + - JSQWebViewController + - MenuItemKit + - Nimble + - Quick + - Realm + - RealmSwift + - SSZipArchive + - ZFDragableModalTransition EXTERNAL SOURCES: FolioReaderKit: - :path: ../ + :path: "../" SPEC CHECKSUMS: - AEXML: 6fc6433aa35bdc15dd8eb8d54eb7aa4520a010eb - FolioReaderKit: 8aca75320da0de2164daa9c498bd2eed3c3cafd3 - FontBlaster: 0f4a3e2f965968e2dfc3f7f5cec7214c3f3b2f07 - JSQWebViewController: 0461aa42612b221571556df61d9c09f080cb2eef - MenuItemKit: 9af69953dc983803ee85230e205fadbac0f26213 - Nimble: 56fc9f5020effa2206de22c3dd910f4fb011b92f - Quick: 5d290df1c69d5ee2f0729956dcf0fd9a30447eaa - Realm: 6f23fd1f178a09342eac21bfa7c2bf4312a7a180 - RealmSwift: 695393add1b8f9d5fa75dd16e6355cf3935f71e2 - SSZipArchive: 04547dfa448be5ed7ecbaf7eaf8a6e9eb9b42997 + AEXML: 5ebafc1b75e0bcf0f1b09b8ca8fed2d5a199479b + FolioReaderKit: 47af4947287e66a902d5d8af9577e10b8ad230f4 + FontBlaster: 84229df8e3a7a6dacb190565bc543747a0c323f9 + JSQWebViewController: 51041569b75d19dbb6b7fe0b7ae053c32409a9be + MenuItemKit: d9b539b28fdbbd7980d6f3668b9cd6daefeabd9b + Nimble: bfe1f814edabba69ff145cb1283e04ed636a67f2 + Quick: 58d203b1c5e27fff7229c4c1ae445ad7069a7a08 + Realm: 42d1c38a5b1bbcc828b48a7ce702cb86fc68adf4 + RealmSwift: d31937ca6a6ee54acde64ec839523c0a3c04924b + SSZipArchive: 14401ade5f8e82aba1ff03e9f88e9de60937ae60 ZFDragableModalTransition: 0d294eaaba6edfcb9839595de765f9ca06a4b524 -PODFILE CHECKSUM: 38a26e71a3566d844488629f70fa094d06893b23 +PODFILE CHECKSUM: d5e64429a71bc13b6eceb790b04656d8082e4d66 -COCOAPODS: 1.3.1 +COCOAPODS: 1.5.2 diff --git a/Example/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json index ec6730cd9..1b6967475 100644 --- a/Example/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -97,6 +97,11 @@ "idiom" : "ipad", "filename" : "Icon-iPadPro@2x.png", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/FolioReaderKit.podspec b/FolioReaderKit.podspec index 2fe1d6d5e..4a0388c10 100644 --- a/FolioReaderKit.podspec +++ b/FolioReaderKit.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "FolioReaderKit" - s.version = "1.2.0" + s.version = "1.3.0" s.summary = "A Swift ePub reader and parser framework for iOS." s.description = <<-DESC Written in Swift. @@ -13,8 +13,9 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/FolioReader/FolioReaderKit.git", :tag => s.version.to_s } s.social_media_url = 'https://twitter.com/hebertialmeida' - s.platform = :ios, '8.0' - s.requires_arc = true + s.swift_version = '4.0' + s.platform = :ios, '8.0' + s.requires_arc = true s.source_files = [ 'Source/*.{h,swift}', @@ -29,12 +30,12 @@ Pod::Spec.new do |s| s.public_header_files = 'Source/*.h' s.libraries = "z" - s.dependency 'SSZipArchive', '~> 1.8' - s.dependency 'MenuItemKit', '2.0' - s.dependency 'ZFDragableModalTransition', '~> 0.6' - s.dependency 'AEXML', '4.0' - s.dependency 'FontBlaster', '3.0.0' - s.dependency 'JSQWebViewController', '~> 5.0' - s.dependency 'RealmSwift', '3.0.2' + s.dependency 'SSZipArchive', '2.1.1' + s.dependency 'MenuItemKit', '3.0.0' + s.dependency 'ZFDragableModalTransition', '0.6' + s.dependency 'AEXML', '4.2.2' + s.dependency 'FontBlaster', '4.0.1' + s.dependency 'JSQWebViewController', '6.0.0' + s.dependency 'RealmSwift', '3.1.1' end diff --git a/FolioReaderKit.xcodeproj/project.pbxproj b/FolioReaderKit.xcodeproj/project.pbxproj index ae3dd71e3..23a628d4e 100644 --- a/FolioReaderKit.xcodeproj/project.pbxproj +++ b/FolioReaderKit.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 1A41E8912031E22300A8F70C /* MediaType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A41E8902031E22300A8F70C /* MediaType.swift */; }; 1A65DDCC1DA73F8E0033C277 /* MenuItemKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A65DDCB1DA73F8D0033C277 /* MenuItemKit.framework */; }; 1A65DDD21DA744190033C277 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A65DDD01DA744190033C277 /* Realm.framework */; }; 1A65DDD31DA744190033C277 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A65DDD11DA744190033C277 /* RealmSwift.framework */; }; @@ -14,7 +15,6 @@ 1A65DDD71DA7450A0033C277 /* FolioReaderQuoteShare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A65DDD61DA7450A0033C277 /* FolioReaderQuoteShare.swift */; }; 1A958F911D397BE900D56699 /* FRBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F051D397BE900D56699 /* FRBook.swift */; }; 1A958F921D397BE900D56699 /* FREpubParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F061D397BE900D56699 /* FREpubParser.swift */; }; - 1A958F931D397BE900D56699 /* FRMediaType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F071D397BE900D56699 /* FRMediaType.swift */; }; 1A958F941D397BE900D56699 /* FRMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F081D397BE900D56699 /* FRMetadata.swift */; }; 1A958F951D397BE900D56699 /* FRResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F091D397BE900D56699 /* FRResource.swift */; }; 1A958F961D397BE900D56699 /* FRResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F0A1D397BE900D56699 /* FRResources.swift */; }; @@ -60,6 +60,42 @@ 1A9590131D397BE900D56699 /* ScrollScrubber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F901D397BE900D56699 /* ScrollScrubber.swift */; }; 1A9590151D397C1300D56699 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A9590141D397C1300D56699 /* Images.xcassets */; }; 1A9590171D397CAF00D56699 /* FolioReaderKit.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 1A9590161D397CAF00D56699 /* FolioReaderKit.podspec */; }; + 256AE60B20A1D4DD00EAD746 /* FolioReaderAddHighlightNote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 256AE60A20A1D4DD00EAD746 /* FolioReaderAddHighlightNote.swift */; }; + 3A27F08C1FD9BE5800D84A57 /* FolioReaderUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27F08A1FD9BE5800D84A57 /* FolioReaderUserDefaults.swift */; }; + 3A27F08E1FD9BE5800D84A57 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27F08B1FD9BE5800D84A57 /* Extensions.swift */; }; + 3A27F09D1FD9C24A00D84A57 /* FRBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F051D397BE900D56699 /* FRBook.swift */; }; + 3A27F09E1FD9C24A00D84A57 /* FREpubParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F061D397BE900D56699 /* FREpubParser.swift */; }; + 3A27F0A01FD9C24A00D84A57 /* FRMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F081D397BE900D56699 /* FRMetadata.swift */; }; + 3A27F0A11FD9C24A00D84A57 /* FRResource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F091D397BE900D56699 /* FRResource.swift */; }; + 3A27F0A21FD9C24A00D84A57 /* FRResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F0A1D397BE900D56699 /* FRResources.swift */; }; + 3A27F0A31FD9C24A00D84A57 /* FRSmilElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F0B1D397BE900D56699 /* FRSmilElement.swift */; }; + 3A27F0A41FD9C24A00D84A57 /* FRSmils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F0C1D397BE900D56699 /* FRSmils.swift */; }; + 3A27F0A51FD9C24A00D84A57 /* FRSpine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F0D1D397BE900D56699 /* FRSpine.swift */; }; + 3A27F0A61FD9C24A00D84A57 /* FRTocReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F0E1D397BE900D56699 /* FRTocReference.swift */; }; + 3A27F0AF1FD9C25500D84A57 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27F08B1FD9BE5800D84A57 /* Extensions.swift */; }; + 3A27F0B01FD9C25500D84A57 /* FolioReaderAudioPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F0F1D397BE900D56699 /* FolioReaderAudioPlayer.swift */; }; + 3A27F0B11FD9C25500D84A57 /* FolioReaderCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F101D397BE900D56699 /* FolioReaderCenter.swift */; }; + 3A27F0B21FD9C25500D84A57 /* FolioReaderChapterList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F111D397BE900D56699 /* FolioReaderChapterList.swift */; }; + 3A27F0B31FD9C25500D84A57 /* FolioReaderChapterListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F121D397BE900D56699 /* FolioReaderChapterListCell.swift */; }; + 3A27F0B41FD9C25500D84A57 /* FolioReaderConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F131D397BE900D56699 /* FolioReaderConfig.swift */; }; + 3A27F0B51FD9C25500D84A57 /* FolioReaderContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F141D397BE900D56699 /* FolioReaderContainer.swift */; }; + 3A27F0B61FD9C25500D84A57 /* FolioReaderFontsMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F151D397BE900D56699 /* FolioReaderFontsMenu.swift */; }; + 3A27F0B71FD9C25500D84A57 /* FolioReaderHighlightList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F161D397BE900D56699 /* FolioReaderHighlightList.swift */; }; + 3A27F0B81FD9C25500D84A57 /* FolioReaderKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F181D397BE900D56699 /* FolioReaderKit.swift */; }; + 3A27F0B91FD9C25500D84A57 /* FolioReaderPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F191D397BE900D56699 /* FolioReaderPage.swift */; }; + 3A27F0BA1FD9C25500D84A57 /* FolioReaderPageIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F1A1D397BE900D56699 /* FolioReaderPageIndicator.swift */; }; + 3A27F0BB1FD9C25500D84A57 /* FolioReaderPlayerMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F1B1D397BE900D56699 /* FolioReaderPlayerMenu.swift */; }; + 3A27F0BC1FD9C25500D84A57 /* FolioReaderQuoteShare.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A65DDD61DA7450A0033C277 /* FolioReaderQuoteShare.swift */; }; + 3A27F0BD1FD9C25500D84A57 /* FolioReaderSharingProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F1C1D397BE900D56699 /* FolioReaderSharingProvider.swift */; }; + 3A27F0BE1FD9C25500D84A57 /* FolioReaderUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27F08A1FD9BE5800D84A57 /* FolioReaderUserDefaults.swift */; }; + 3A27F0BF1FD9C25500D84A57 /* FolioReaderWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD5EEB81D9433C100E42810 /* FolioReaderWebView.swift */; }; + 3A27F0C21FD9C25C00D84A57 /* PageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F241D397BE900D56699 /* PageViewController.swift */; }; + 3A27F0C31FD9C25C00D84A57 /* QuoteImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A65DDD41DA744410033C277 /* QuoteImage.swift */; }; + 3A27F0C41FD9C25C00D84A57 /* ScrollScrubber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F901D397BE900D56699 /* ScrollScrubber.swift */; }; + 3A27F0C51FD9C31E00D84A57 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A65DDD01DA744190033C277 /* Realm.framework */; }; + 3A27F0C61FD9C31E00D84A57 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A65DDD11DA744190033C277 /* RealmSwift.framework */; }; + 3A27F0C71FD9C33A00D84A57 /* Highlight+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F211D397BE900D56699 /* Highlight+Helper.swift */; }; + 3A27F0C81FD9C33A00D84A57 /* Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A958F231D397BE900D56699 /* Highlight.swift */; }; 3AD5EEB91D9433C100E42810 /* FolioReaderWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD5EEB81D9433C100E42810 /* FolioReaderWebView.swift */; }; B0D6990F1D035FA2003B4CCD /* FolioReaderKit.h in Headers */ = {isa = PBXBuildFile; fileRef = B0D6990E1D035FA2003B4CCD /* FolioReaderKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; B0D699161D035FA2003B4CCD /* FolioReaderKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0D6990B1D035FA2003B4CCD /* FolioReaderKit.framework */; }; @@ -85,6 +121,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 1A41E8902031E22300A8F70C /* MediaType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaType.swift; sourceTree = ""; }; 1A65DDCB1DA73F8D0033C277 /* MenuItemKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MenuItemKit.framework; path = Carthage/Build/iOS/MenuItemKit.framework; sourceTree = ""; }; 1A65DDD01DA744190033C277 /* Realm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Realm.framework; path = Carthage/Build/iOS/Realm.framework; sourceTree = ""; }; 1A65DDD11DA744190033C277 /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RealmSwift.framework; path = Carthage/Build/iOS/RealmSwift.framework; sourceTree = ""; }; @@ -92,7 +129,6 @@ 1A65DDD61DA7450A0033C277 /* FolioReaderQuoteShare.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolioReaderQuoteShare.swift; sourceTree = ""; }; 1A958F051D397BE900D56699 /* FRBook.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FRBook.swift; sourceTree = ""; }; 1A958F061D397BE900D56699 /* FREpubParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FREpubParser.swift; sourceTree = ""; }; - 1A958F071D397BE900D56699 /* FRMediaType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FRMediaType.swift; sourceTree = ""; }; 1A958F081D397BE900D56699 /* FRMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FRMetadata.swift; sourceTree = ""; }; 1A958F091D397BE900D56699 /* FRResource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FRResource.swift; sourceTree = ""; }; 1A958F0A1D397BE900D56699 /* FRResources.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FRResources.swift; sourceTree = ""; }; @@ -138,6 +174,9 @@ 1A958F901D397BE900D56699 /* ScrollScrubber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollScrubber.swift; sourceTree = ""; }; 1A9590141D397C1300D56699 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 1A9590161D397CAF00D56699 /* FolioReaderKit.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FolioReaderKit.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 256AE60A20A1D4DD00EAD746 /* FolioReaderAddHighlightNote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolioReaderAddHighlightNote.swift; sourceTree = ""; }; + 3A27F08A1FD9BE5800D84A57 /* FolioReaderUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolioReaderUserDefaults.swift; sourceTree = ""; }; + 3A27F08B1FD9BE5800D84A57 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 3AD5EEB81D9433C100E42810 /* FolioReaderWebView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FolioReaderWebView.swift; sourceTree = ""; }; B0D6990B1D035FA2003B4CCD /* FolioReaderKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FolioReaderKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B0D6990E1D035FA2003B4CCD /* FolioReaderKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FolioReaderKit.h; sourceTree = ""; }; @@ -175,6 +214,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 3A27F0C51FD9C31E00D84A57 /* Realm.framework in Frameworks */, + 3A27F0C61FD9C31E00D84A57 /* RealmSwift.framework in Frameworks */, B0D699161D035FA2003B4CCD /* FolioReaderKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -196,9 +237,13 @@ isa = PBXGroup; children = ( 1A958F041D397BE900D56699 /* EPUBCore */, + 1A958F1D1D397BE900D56699 /* Models */, + 1A958F251D397BE900D56699 /* Resources */, + 3A27F08B1FD9BE5800D84A57 /* Extensions.swift */, 1A958F0F1D397BE900D56699 /* FolioReaderAudioPlayer.swift */, 1A958F101D397BE900D56699 /* FolioReaderCenter.swift */, 1A958F111D397BE900D56699 /* FolioReaderChapterList.swift */, + 256AE60A20A1D4DD00EAD746 /* FolioReaderAddHighlightNote.swift */, 1A958F121D397BE900D56699 /* FolioReaderChapterListCell.swift */, 1A958F131D397BE900D56699 /* FolioReaderConfig.swift */, 1A958F141D397BE900D56699 /* FolioReaderContainer.swift */, @@ -211,12 +256,11 @@ 1A958F1B1D397BE900D56699 /* FolioReaderPlayerMenu.swift */, 1A65DDD61DA7450A0033C277 /* FolioReaderQuoteShare.swift */, 1A958F1C1D397BE900D56699 /* FolioReaderSharingProvider.swift */, + 3A27F08A1FD9BE5800D84A57 /* FolioReaderUserDefaults.swift */, 3AD5EEB81D9433C100E42810 /* FolioReaderWebView.swift */, 1A958F241D397BE900D56699 /* PageViewController.swift */, 1A65DDD41DA744410033C277 /* QuoteImage.swift */, 1A958F901D397BE900D56699 /* ScrollScrubber.swift */, - 1A958F1D1D397BE900D56699 /* Models */, - 1A958F251D397BE900D56699 /* Resources */, ); path = Source; sourceTree = SOURCE_ROOT; @@ -224,9 +268,9 @@ 1A958F041D397BE900D56699 /* EPUBCore */ = { isa = PBXGroup; children = ( + 1A41E8902031E22300A8F70C /* MediaType.swift */, 1A958F051D397BE900D56699 /* FRBook.swift */, 1A958F061D397BE900D56699 /* FREpubParser.swift */, - 1A958F071D397BE900D56699 /* FRMediaType.swift */, 1A958F081D397BE900D56699 /* FRMetadata.swift */, 1A958F091D397BE900D56699 /* FRResource.swift */, 1A958F0A1D397BE900D56699 /* FRResources.swift */, @@ -416,7 +460,6 @@ B0D699071D035FA2003B4CCD /* Frameworks */, B0D699081D035FA2003B4CCD /* Headers */, B0D699091D035FA2003B4CCD /* Resources */, - 1A65DDCF1DA7409C0033C277 /* ShellScript */, ); buildRules = ( ); @@ -452,18 +495,17 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = FolioReader; TargetAttributes = { B0D6990A1D035FA2003B4CCD = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = 32F2T8EJ6G; LastSwiftMigration = 0800; }; B0D699141D035FA2003B4CCD = { CreatedOnToolsVersion = 7.3.1; DevelopmentTeam = 32F2T8EJ6G; - LastSwiftMigration = 0800; + LastSwiftMigration = 0920; }; }; }; @@ -522,24 +564,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 1A65DDCF1DA7409C0033C277 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/Carthage/Build/iOS/Realm.framework", - "$(SRCROOT)/Carthage/Build/iOS/RealmSwift.framework", - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ B0D699061D035FA2003B4CCD /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -556,7 +580,9 @@ 3AD5EEB91D9433C100E42810 /* FolioReaderWebView.swift in Sources */, 1A958FA41D397BE900D56699 /* FolioReaderKit.swift in Sources */, 1A65DDD71DA7450A0033C277 /* FolioReaderQuoteShare.swift in Sources */, + 3A27F08C1FD9BE5800D84A57 /* FolioReaderUserDefaults.swift in Sources */, 1A958FA21D397BE900D56699 /* FolioReaderHighlightList.swift in Sources */, + 256AE60B20A1D4DD00EAD746 /* FolioReaderAddHighlightNote.swift in Sources */, 1A958FA71D397BE900D56699 /* FolioReaderPlayerMenu.swift in Sources */, 1A958F921D397BE900D56699 /* FREpubParser.swift in Sources */, 1A958F9C1D397BE900D56699 /* FolioReaderCenter.swift in Sources */, @@ -564,6 +590,8 @@ 1A958FAD1D397BE900D56699 /* Highlight.swift in Sources */, 1A958F981D397BE900D56699 /* FRSmils.swift in Sources */, 1A958F971D397BE900D56699 /* FRSmilElement.swift in Sources */, + 1A41E8912031E22300A8F70C /* MediaType.swift in Sources */, + 3A27F08E1FD9BE5800D84A57 /* Extensions.swift in Sources */, 1A958F9D1D397BE900D56699 /* FolioReaderChapterList.swift in Sources */, 1A958F951D397BE900D56699 /* FRResource.swift in Sources */, 1A958F9B1D397BE900D56699 /* FolioReaderAudioPlayer.swift in Sources */, @@ -571,7 +599,6 @@ 1A958F9A1D397BE900D56699 /* FRTocReference.swift in Sources */, 1A958F911D397BE900D56699 /* FRBook.swift in Sources */, 1A958F941D397BE900D56699 /* FRMetadata.swift in Sources */, - 1A958F931D397BE900D56699 /* FRMediaType.swift in Sources */, 1A9590131D397BE900D56699 /* ScrollScrubber.swift in Sources */, B0D69CC81D0387F7003B4CCD /* HADiscreteSlider.swift in Sources */, 1A65DDD51DA744410033C277 /* QuoteImage.swift in Sources */, @@ -585,7 +612,38 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3A27F0A31FD9C24A00D84A57 /* FRSmilElement.swift in Sources */, + 3A27F0A11FD9C24A00D84A57 /* FRResource.swift in Sources */, + 3A27F0BC1FD9C25500D84A57 /* FolioReaderQuoteShare.swift in Sources */, + 3A27F0B01FD9C25500D84A57 /* FolioReaderAudioPlayer.swift in Sources */, + 3A27F0A41FD9C24A00D84A57 /* FRSmils.swift in Sources */, + 3A27F0B31FD9C25500D84A57 /* FolioReaderChapterListCell.swift in Sources */, + 3A27F0BD1FD9C25500D84A57 /* FolioReaderSharingProvider.swift in Sources */, B0D6991B1D035FA2003B4CCD /* FolioReaderKitTests.swift in Sources */, + 3A27F0BF1FD9C25500D84A57 /* FolioReaderWebView.swift in Sources */, + 3A27F0BA1FD9C25500D84A57 /* FolioReaderPageIndicator.swift in Sources */, + 3A27F0A51FD9C24A00D84A57 /* FRSpine.swift in Sources */, + 3A27F0B81FD9C25500D84A57 /* FolioReaderKit.swift in Sources */, + 3A27F0C21FD9C25C00D84A57 /* PageViewController.swift in Sources */, + 3A27F0A01FD9C24A00D84A57 /* FRMetadata.swift in Sources */, + 3A27F0B21FD9C25500D84A57 /* FolioReaderChapterList.swift in Sources */, + 3A27F0B41FD9C25500D84A57 /* FolioReaderConfig.swift in Sources */, + 3A27F0B61FD9C25500D84A57 /* FolioReaderFontsMenu.swift in Sources */, + 3A27F0AF1FD9C25500D84A57 /* Extensions.swift in Sources */, + 3A27F0C81FD9C33A00D84A57 /* Highlight.swift in Sources */, + 3A27F0B51FD9C25500D84A57 /* FolioReaderContainer.swift in Sources */, + 3A27F0C71FD9C33A00D84A57 /* Highlight+Helper.swift in Sources */, + 3A27F0B11FD9C25500D84A57 /* FolioReaderCenter.swift in Sources */, + 3A27F0A61FD9C24A00D84A57 /* FRTocReference.swift in Sources */, + 3A27F0BE1FD9C25500D84A57 /* FolioReaderUserDefaults.swift in Sources */, + 3A27F0B91FD9C25500D84A57 /* FolioReaderPage.swift in Sources */, + 3A27F09D1FD9C24A00D84A57 /* FRBook.swift in Sources */, + 3A27F0BB1FD9C25500D84A57 /* FolioReaderPlayerMenu.swift in Sources */, + 3A27F0C41FD9C25C00D84A57 /* ScrollScrubber.swift in Sources */, + 3A27F0C31FD9C25C00D84A57 /* QuoteImage.swift in Sources */, + 3A27F0B71FD9C25500D84A57 /* FolioReaderHighlightList.swift in Sources */, + 3A27F09E1FD9C24A00D84A57 /* FREpubParser.swift in Sources */, + 3A27F0A21FD9C24A00D84A57 /* FRResources.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -609,14 +667,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -645,6 +709,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -660,14 +725,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -689,6 +760,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -699,9 +771,9 @@ B0D699201D035FA2003B4CCD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -716,16 +788,15 @@ PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderKit; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; }; name = Debug; }; B0D699211D035FA2003B4CCD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = 32F2T8EJ6G; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -740,7 +811,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderKit; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; }; name = Release; }; @@ -748,11 +818,15 @@ isa = XCBuildConfiguration; buildSettings = { DEVELOPMENT_TEAM = 32F2T8EJ6G; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = FolioReaderKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; }; name = Debug; }; @@ -760,11 +834,15 @@ isa = XCBuildConfiguration; buildSettings = { DEVELOPMENT_TEAM = 32F2T8EJ6G; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = FolioReaderKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.folioreader.FolioReaderKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = On; }; name = Release; }; diff --git a/FolioReaderKit.xcodeproj/xcshareddata/xcschemes/FolioReaderKit.xcscheme b/FolioReaderKit.xcodeproj/xcshareddata/xcschemes/FolioReaderKit.xcscheme index e11054961..2e3f859ca 100644 --- a/FolioReaderKit.xcodeproj/xcshareddata/xcschemes/FolioReaderKit.xcscheme +++ b/FolioReaderKit.xcodeproj/xcshareddata/xcschemes/FolioReaderKit.xcscheme @@ -1,6 +1,6 @@ CFBundleSignature ???? CFBundleVersion - 1 + 1 diff --git a/LICENSE b/LICENSE index 8a61285b3..42ad82019 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2017, Heberti Almeida +Copyright (c) 2015-2018, Heberti Almeida All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/MIGRATION.md b/MIGRATION.md index 89f481515..1110dfc85 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -65,7 +65,7 @@ public init(withConfig config: FolioReaderConfig, folioReader: FolioReader, epub ### Class: FolioReaderDelegate The function `folioReaderDidClosed` has been renamed `folioReaderDidClose`. -It also has a new `FolioReader parameter. +It also has a new `FolioReader` parameter. ``` func folioReaderDidClose(_ folioReader: FolioReader) @@ -97,7 +97,7 @@ func parseCoverImage(_ epubPath: String, unzipPath: String? = nil) -> UIImage? ### Class: UIKit classes extensions -The following functions now need a FolioReaderConfig object as parameter: +The following functions now need a `FolioReaderConfig` object as parameter: ``` UICollectionViewScrollDirection.direction(withConfiguration readerConfig: FolioReaderConfig) -> UICollectionViewScrollDirection diff --git a/Package.swift b/Package.swift index 924922789..753e81d7b 100644 --- a/Package.swift +++ b/Package.swift @@ -3,12 +3,12 @@ import PackageDescription let package = Package( name: "FolioReaderKit", dependencies: [ - .Package(url: "https://github.com/ZipArchive/ZipArchive.git", majorVersion: 1, minor: 4), - .Package(url: "https://github.com/cxa/UIMenuItem-CXAImageSupport.git", majorVersion: 0, minor: 0), + .Package(url: "https://github.com/ZipArchive/ZipArchive.git", majorVersion: 2, minor: 1), + .Package(url: "https://github.com/cxa/MenuItemKit.git", majorVersion: 3, minor: 0), .Package(url: "https://github.com/zoonooz/ZFDragableModalTransition.git", majorVersion: 0, minor: 6), - .Package(url: "https://github.com/tadija/AEXML.git", majorVersion: 3, minor: 0), - .Package(url: "https://github.com/ArtSabintsev/FontBlaster.git", majorVersion: 2, minor: 1), - .Package(url: "https://github.com/jessesquires/JSQWebViewController.git", majorVersion: 3, minor: 0), - .Package(url: "https://github.com/realm/realm-cocoa.git", majorVersion: 1, minor: 0), + .Package(url: "https://github.com/tadija/AEXML.git", majorVersion: 4, minor: 2), + .Package(url: "https://github.com/ArtSabintsev/FontBlaster.git", majorVersion: 4, minor: 0), + .Package(url: "https://github.com/jessesquires/JSQWebViewController.git", majorVersion: 6, minor: 0), + .Package(url: "https://github.com/realm/realm-cocoa.git", majorVersion: 3, minor: 1), ] ) diff --git a/README.md b/README.md index d5216a4ad..35d77fb98 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ Then, follow the steps as described in Carthage's [README](https://github.com/Ca ## Requirements - iOS 8.0+ -- Xcode 8.3+ +- Xcode 9+ ## Basic Usage @@ -132,12 +132,14 @@ class StoryboardFolioReaderContrainer: FolioReaderContainer { } } ``` + Go to your storyboard file, choose or create the view controller that should present the epub reader. In the identity inspector set StoryboardFolioReaderContrainer as class. ## Documentation Checkout [Example](/Example) and [API Documentation](http://cocoadocs.org/docsets/FolioReaderKit) You can always use the header-doc. (use **alt+click** in Xcode) + ### Migration diff --git a/Source/EPUBCore/FRBook.swift b/Source/EPUBCore/FRBook.swift index cb9c4db20..bf8887cbe 100755 --- a/Source/EPUBCore/FRBook.swift +++ b/Source/EPUBCore/FRBook.swift @@ -10,82 +10,78 @@ import UIKit open class FRBook: NSObject { - var resources = FRResources() var metadata = FRMetadata() var spine = FRSpine() var smils = FRSmils() - var tableOfContents: [FRTocReference]! - var flatTableOfContents: [FRTocReference]! - var opfResource: FRResource! - var tocResource: FRResource? - var coverImage: FRResource? var version: Double? - var uniqueIdentifier: String? - var name: String? - - func hasAudio() -> Bool { - return smils.smils.count > 0 ? true : false + + public var opfResource: FRResource! + public var tocResource: FRResource? + public var uniqueIdentifier: String? + public var coverImage: FRResource? + public var name: String? + public var resources = FRResources() + public var tableOfContents: [FRTocReference]! + public var flatTableOfContents: [FRTocReference]! + + var hasAudio: Bool { + return smils.smils.count > 0 } - func title() -> String? { + var title: String? { return metadata.titles.first } - func authorName() -> String? { + var authorName: String? { return metadata.creators.first?.name } // MARK: - Media Overlay Metadata // http://www.idpf.org/epub/301/spec/epub-mediaoverlays.html#sec-package-metadata - func duration() -> String? { - return metadata.findMetaByProperty("media:duration"); - } - - // @NOTE: should "#" be automatically prefixed with the ID? - func durationFor(_ ID: String) -> String? { - return metadata.findMetaByProperty("media:duration", refinedBy: ID) + var duration: String? { + return metadata.find(byProperty: "media:duration")?.value } - - func activeClass() -> String { - guard let className = metadata.findMetaByProperty("media:active-class") else { + var activeClass: String { + guard let className = metadata.find(byProperty: "media:active-class")?.value else { return "epub-media-overlay-active" } return className } - func playbackActiveClass() -> String { - guard let className = metadata.findMetaByProperty("media:playback-active-class") else { + var playbackActiveClass: String { + guard let className = metadata.find(byProperty: "media:playback-active-class")?.value else { return "epub-media-overlay-playing" } return className } - // MARK: - Media Overlay (SMIL) retrieval /** Get Smil File from a resource (if it has a media-overlay) */ - func smilFileForResource(_ resource: FRResource!) -> FRSmilFile! { - if( resource == nil || resource.mediaOverlay == nil ){ - return nil - } + func smilFileForResource(_ resource: FRResource?) -> FRSmilFile? { + guard let resource = resource, let mediaOverlay = resource.mediaOverlay else { return nil } // lookup the smile resource to get info about the file - let smilResource = resources.findById(resource.mediaOverlay) + guard let smilResource = resources.findById(mediaOverlay) else { return nil } // use the resource to get the file - return smils.findByHref( smilResource!.href ) + return smils.findByHref(smilResource.href) } - func smilFileForHref(_ href: String) -> FRSmilFile! { + func smilFile(forHref href: String) -> FRSmilFile? { return smilFileForResource(resources.findByHref(href)) } - func smilFileForId(_ ID: String) -> FRSmilFile! { + func smilFile(forId ID: String) -> FRSmilFile? { return smilFileForResource(resources.findById(ID)) } + // @NOTE: should "#" be automatically prefixed with the ID? + func duration(for ID: String) -> String? { + return metadata.find(byProperty: "media:duration", refinedBy: ID)?.value + } } diff --git a/Source/EPUBCore/FREpubParser.swift b/Source/EPUBCore/FREpubParser.swift index 440685416..a9879c58b 100755 --- a/Source/EPUBCore/FREpubParser.swift +++ b/Source/EPUBCore/FREpubParser.swift @@ -7,205 +7,219 @@ // import UIKit +import AEXML #if COCOAPODS - import SSZipArchive +import SSZipArchive #else - import ZipArchive +import ZipArchive #endif -import AEXML class FREpubParser: NSObject, SSZipArchiveDelegate { let book = FRBook() - var bookBasePath: String! - var resourcesBasePath: String! - var shouldRemoveEpub = true - - fileprivate var epubPathToRemove: String? + private var resourcesBasePath = "" + private var shouldRemoveEpub = true + private var epubPathToRemove: String? /// Parse the Cover Image from an epub file. /// /// - Parameters: - /// - epubPath: Epub path on the disk + /// - epubPath: Epub path on the disk. /// - unzipPath: Path to unzip the compressed epub. - /// - Returns: An UIImage object - func parseCoverImage(_ epubPath: String, unzipPath: String? = nil) throws -> UIImage? { - guard - let book = try readEpub(epubPath: epubPath, removeEpub: false, unzipPath: unzipPath), + /// - Returns: The book cover as UIImage object + /// - Throws: `FolioReaderError` + func parseCoverImage(_ epubPath: String, unzipPath: String? = nil) throws -> UIImage { + guard let book = try? readEpub(epubPath: epubPath, removeEpub: false, unzipPath: unzipPath), let coverImage = book.coverImage else { - throw FolioReaderError(kind: .CoverNotAvailable) + throw FolioReaderError.coverNotAvailable } - return UIImage(contentsOfFile: coverImage.fullHref) + + guard let image = UIImage(contentsOfFile: coverImage.fullHref) else { + throw FolioReaderError.invalidImage(path: coverImage.fullHref) + } + + return image } - func parseTitle(_ epubPath: String) throws -> String? { - guard let book = try readEpub(epubPath: epubPath, removeEpub: false), let title = book.title() else { - throw FolioReaderError(kind: .TitleNotAvailable) + /// Parse the book title from an epub file. + /// + /// - Parameters: + /// - epubPath: Epub path on the disk. + /// - unzipPath: Path to unzip the compressed epub. + /// - Returns: The book title + /// - Throws: `FolioReaderError` + func parseTitle(_ epubPath: String, unzipPath: String? = nil) throws -> String { + guard let book = try? readEpub(epubPath: epubPath, removeEpub: false, unzipPath: unzipPath), let title = book.title else { + throw FolioReaderError.titleNotAvailable } return title } - func parseAuthorName(_ epubPath: String) throws -> String? { - guard let book = try readEpub(epubPath: epubPath, removeEpub: false), let authorName = book.authorName() else { - throw FolioReaderError(kind: .AuthorNameNotAvailable) + + /// Parse the book Author name from an epub file. + /// + /// - Parameters: + /// - epubPath: Epub path on the disk. + /// - unzipPath: Path to unzip the compressed epub. + /// - Returns: The author name + /// - Throws: `FolioReaderError` + func parseAuthorName(_ epubPath: String, unzipPath: String? = nil) throws -> String { + guard let book = try? readEpub(epubPath: epubPath, removeEpub: false, unzipPath: unzipPath), let authorName = book.authorName else { + throw FolioReaderError.authorNameNotAvailable } return authorName } - /** - Unzip, delete and read an epub file. - Returns a FRBook. - */ - func readEpub(epubPath withEpubPath: String, removeEpub: Bool = true, unzipPath: String? = nil) throws -> FRBook? { + /// Unzip, delete and read an epub file. + /// + /// - Parameters: + /// - withEpubPath: Epub path on the disk + /// - removeEpub: Should remove the original file? + /// - unzipPath: Path to unzip the compressed epub. + /// - Returns: `FRBook` Object + /// - Throws: `FolioReaderError` + func readEpub(epubPath withEpubPath: String, removeEpub: Bool = true, unzipPath: String? = nil) throws -> FRBook { epubPathToRemove = withEpubPath shouldRemoveEpub = removeEpub var isDir: ObjCBool = false let fileManager = FileManager.default - let bookName = (withEpubPath as NSString).lastPathComponent + let bookName = withEpubPath.lastPathComponent + var bookBasePath = "" - if let path = unzipPath, (fileManager.fileExists(atPath: path) == true) { + if let path = unzipPath, fileManager.fileExists(atPath: path) { bookBasePath = path } else { bookBasePath = kApplicationDocumentsDirectory } - bookBasePath = (bookBasePath as NSString).appendingPathComponent(bookName) + bookBasePath = bookBasePath.appendingPathComponent(bookName) guard fileManager.fileExists(atPath: withEpubPath) else { - throw FolioReaderError(kind: .BookNotAvailable) + throw FolioReaderError.bookNotAvailable } // Unzip if necessary - var needsUnzip = false - if fileManager.fileExists(atPath: bookBasePath, isDirectory:&isDir) { - if !isDir.boolValue { needsUnzip = true } - } else { - needsUnzip = true - } + let needsUnzip = !fileManager.fileExists(atPath: bookBasePath, isDirectory:&isDir) || !isDir.boolValue if needsUnzip { SSZipArchive.unzipFile(atPath: withEpubPath, toDestination: bookBasePath, delegate: self) } // Skip from backup this folder - addSkipBackupAttributeToItemAtURL(URL(fileURLWithPath: bookBasePath, isDirectory: true)) + try addSkipBackupAttributeToItemAtURL(URL(fileURLWithPath: bookBasePath, isDirectory: true)) - self.book.name = bookName - try readContainer() - try readOpf() + book.name = bookName + try readContainer(with: bookBasePath) + try readOpf(with: bookBasePath) return self.book } - /** - Read and parse container.xml file. - */ - fileprivate func readContainer() throws { + /// Read and parse container.xml file. + /// + /// - Parameter bookBasePath: The base book path + /// - Throws: `FolioReaderError` + private func readContainer(with bookBasePath: String) throws { let containerPath = "META-INF/container.xml" - do { - let containerData = try Data(contentsOf: URL(fileURLWithPath: (bookBasePath as NSString).appendingPathComponent(containerPath)), options: .alwaysMapped) - let xmlDoc = try AEXMLDocument(xml: containerData) - let opfResource = FRResource() - opfResource.href = xmlDoc.root["rootfiles"]["rootfile"].attributes["full-path"] - opfResource.mediaType = FRMediaType.determineMediaType(xmlDoc.root["rootfiles"]["rootfile"].attributes["full-path"]!) - book.opfResource = opfResource - resourcesBasePath = (bookBasePath as NSString).appendingPathComponent((book.opfResource.href as NSString).deletingLastPathComponent) - - } catch { - throw FolioReaderError(kind : .ErrorInContainer) + let containerData = try Data(contentsOf: URL(fileURLWithPath: bookBasePath.appendingPathComponent(containerPath)), options: .alwaysMapped) + let xmlDoc = try AEXMLDocument(xml: containerData) + let opfResource = FRResource() + opfResource.href = xmlDoc.root["rootfiles"]["rootfile"].attributes["full-path"] + guard let fullPath = xmlDoc.root["rootfiles"]["rootfile"].attributes["full-path"] else { + throw FolioReaderError.fullPathEmpty } + opfResource.mediaType = MediaType.by(fileName: fullPath) + book.opfResource = opfResource + resourcesBasePath = bookBasePath.appendingPathComponent(book.opfResource.href.deletingLastPathComponent) } - /** - Read and parse .opf file. - */ - fileprivate func readOpf() throws { - let opfPath = (bookBasePath as NSString).appendingPathComponent(book.opfResource.href) + /// Read and parse .opf file. + /// + /// - Parameter bookBasePath: The base book path + /// - Throws: `FolioReaderError` + private func readOpf(with bookBasePath: String) throws { + let opfPath = bookBasePath.appendingPathComponent(book.opfResource.href) var identifier: String? - do { - let opfData = try Data(contentsOf: URL(fileURLWithPath: opfPath), options: .alwaysMapped) - let xmlDoc = try AEXMLDocument(xml: opfData) + let opfData = try Data(contentsOf: URL(fileURLWithPath: opfPath), options: .alwaysMapped) + let xmlDoc = try AEXMLDocument(xml: opfData) - // Base OPF info - if let package = xmlDoc.children.first { - identifier = package.attributes["unique-identifier"] + // Base OPF info + if let package = xmlDoc.children.first { + identifier = package.attributes["unique-identifier"] - if let version = package.attributes["version"] { - book.version = Double(version) - } + if let version = package.attributes["version"] { + book.version = Double(version) } + } - // Parse and save each "manifest item" - for item in xmlDoc.root["manifest"]["item"].all! { - let resource = FRResource() - resource.id = item.attributes["id"] - resource.properties = item.attributes["properties"] - resource.href = item.attributes["href"] - resource.fullHref = (resourcesBasePath as NSString).appendingPathComponent(resource.href).removingPercentEncoding - resource.mediaType = FRMediaType.mediaTypeByName(item.attributes["media-type"]!, fileName: resource.href) - resource.mediaOverlay = item.attributes["media-overlay"] - - // if a .smil file is listed in resources, go parse that file now and save it on book model - if (resource.mediaType != nil && resource.mediaType == FRMediaType.SMIL) { - readSmilFile(resource) - } - - book.resources.add(resource) + // Parse and save each "manifest item" + xmlDoc.root["manifest"]["item"].all?.forEach { + let resource = FRResource() + resource.id = $0.attributes["id"] + resource.properties = $0.attributes["properties"] + resource.href = $0.attributes["href"] + resource.fullHref = resourcesBasePath.appendingPathComponent(resource.href).removingPercentEncoding + resource.mediaType = MediaType.by(name: $0.attributes["media-type"] ?? "", fileName: resource.href) + resource.mediaOverlay = $0.attributes["media-overlay"] + + // if a .smil file is listed in resources, go parse that file now and save it on book model + if (resource.mediaType != nil && resource.mediaType == .smil) { + readSmilFile(resource) } - book.smils.basePath = resourcesBasePath + book.resources.add(resource) + } - // Read metadata - book.metadata = readMetadata(xmlDoc.root["metadata"].children) + book.smils.basePath = resourcesBasePath - // Read the book unique identifier - if let uniqueIdentifier = book.metadata.findIdentifierById(identifier) { - book.uniqueIdentifier = uniqueIdentifier - } + // Read metadata + book.metadata = readMetadata(xmlDoc.root["metadata"].children) - // Read the cover image - let coverImageId = book.metadata.findMetaByName("cover") - if let coverResource = book.resources.findById(coverImageId) { - book.coverImage = coverResource - } else if let coverResource = book.resources.findByProperty("cover-image") { - book.coverImage = coverResource - } + // Read the book unique identifier + if let identifier = identifier, let uniqueIdentifier = book.metadata.find(identifierById: identifier) { + book.uniqueIdentifier = uniqueIdentifier.value + } - // Specific TOC for ePub 2 and 3 - // Get the first resource with the NCX mediatype - if let tocResource = book.resources.findByMediaType(FRMediaType.NCX) { - book.tocResource = tocResource - } else if let tocResource = book.resources.findByExtension(FRMediaType.NCX.defaultExtension) { - // Non-standard books may use wrong mediatype, fallback with extension - book.tocResource = tocResource - } else if let tocResource = book.resources.findByProperty("nav") { - book.tocResource = tocResource - } + // Read the cover image + let coverImageId = book.metadata.find(byName: "cover")?.content + if let coverImageId = coverImageId, let coverResource = book.resources.findById(coverImageId) { + book.coverImage = coverResource + } else if let coverResource = book.resources.findByProperty("cover-image") { + book.coverImage = coverResource + } + + // Specific TOC for ePub 2 and 3 + // Get the first resource with the NCX mediatype + if let tocResource = book.resources.findByMediaType(MediaType.ncx) { + book.tocResource = tocResource + } else if let tocResource = book.resources.findByExtension(MediaType.ncx.defaultExtension) { + // Non-standard books may use wrong mediatype, fallback with extension + book.tocResource = tocResource + } else if let tocResource = book.resources.findByProperty("nav") { + book.tocResource = tocResource + } - assert(book.tocResource != nil, "ERROR: Could not find table of contents resource. The book don't have a TOC resource.") + precondition(book.tocResource != nil, "ERROR: Could not find table of contents resource. The book don't have a TOC resource.") - // The book TOC - book.tableOfContents = findTableOfContents() - book.flatTableOfContents = createFlatTOC() + // The book TOC + book.tableOfContents = findTableOfContents() + book.flatTableOfContents = flatTOC - // Read Spine - let spine = xmlDoc.root["spine"] - book.spine = readSpine(spine.children) + // Read Spine + let spine = xmlDoc.root["spine"] + book.spine = readSpine(spine.children) - // Page progress direction `ltr` or `rtl` - if let pageProgressionDirection = spine.attributes["page-progression-direction"] { - book.spine.pageProgressionDirection = pageProgressionDirection - } - } catch { - throw FolioReaderError(kind: .ErrorInOpf) + // Page progress direction `ltr` or `rtl` + if let pageProgressionDirection = spine.attributes["page-progression-direction"] { + book.spine.pageProgressionDirection = pageProgressionDirection } } - /** - Reads and parses a .smil file - */ - fileprivate func readSmilFile(_ resource: FRResource) { + /// Reads and parses a .smil file. + /// + /// - Parameter resource: A `FRResource` to read the smill + private func readSmilFile(_ resource: FRResource) { do { let smilData = try Data(contentsOf: URL(fileURLWithPath: resource.fullHref), options: .alwaysMapped) var smilFile = FRSmilFile(resource: resource) @@ -223,17 +237,16 @@ class FREpubParser: NSObject, SSZipArchiveDelegate { } } - fileprivate func readSmilFileElements(_ children:[AEXMLElement]) -> [FRSmilElement] { + private func readSmilFileElements(_ children: [AEXMLElement]) -> [FRSmilElement] { var data = [FRSmilElement]() // convert each smil element to a FRSmil object - for item in children { - - let smil = FRSmilElement(name: item.name, attributes: item.attributes) + children.forEach{ + let smil = FRSmilElement(name: $0.name, attributes: $0.attributes) // if this element has children, convert them to objects too - if item.children.count > 0 { - smil.children.append(contentsOf: readSmilFileElements(item.children)) + if $0.children.count > 0 { + smil.children.append(contentsOf: readSmilFileElements($0.children)) } data.append(smil) @@ -242,17 +255,17 @@ class FREpubParser: NSObject, SSZipArchiveDelegate { return data } - /** - Read and parse the Table of Contents. - */ - fileprivate func findTableOfContents() -> [FRTocReference] { + /// Read and parse the Table of Contents. + /// + /// - Returns: A list of toc references + private func findTableOfContents() -> [FRTocReference] { var tableOfContent = [FRTocReference]() var tocItems: [AEXMLElement]? guard let tocResource = book.tocResource else { return tableOfContent } - let tocPath = (resourcesBasePath as NSString).appendingPathComponent(tocResource.href) + let tocPath = resourcesBasePath.appendingPathComponent(tocResource.href) do { - if tocResource.mediaType == FRMediaType.NCX { + if tocResource.mediaType == MediaType.ncx { let ncxData = try Data(contentsOf: URL(fileURLWithPath: tocPath), options: .alwaysMapped) let xmlDoc = try AEXMLDocument(xml: ncxData) if let itemsList = xmlDoc.root["navMap"]["navPoint"].all { @@ -275,18 +288,17 @@ class FREpubParser: NSObject, SSZipArchiveDelegate { guard let items = tocItems else { return tableOfContent } for item in items { - tableOfContent.append(readTOCReference(item)) + guard let ref = readTOCReference(item) else { continue } + tableOfContent.append(ref) } return tableOfContent } - /** - Recursively finds a `