{"id":19357922,"url":"https://github.com/milibris/ios-milibris-reader-sdk","last_synced_at":"2026-02-20T17:32:34.056Z","repository":{"id":62457769,"uuid":"513547958","full_name":"miLibris/ios-milibris-reader-sdk","owner":"miLibris","description":"Reader SDK for the miLibris platform","archived":false,"fork":false,"pushed_at":"2024-09-16T13:00:51.000Z","size":56644,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-02T14:21:55.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/miLibris.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-13T14:12:27.000Z","updated_at":"2024-09-16T13:00:54.000Z","dependencies_parsed_at":"2024-04-17T10:31:13.808Z","dependency_job_id":"5ac5c8ba-a9fb-4871-871c-34ed35bb71c2","html_url":"https://github.com/miLibris/ios-milibris-reader-sdk","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miLibris%2Fios-milibris-reader-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miLibris%2Fios-milibris-reader-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miLibris%2Fios-milibris-reader-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miLibris%2Fios-milibris-reader-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/miLibris","download_url":"https://codeload.github.com/miLibris/ios-milibris-reader-sdk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250424998,"owners_count":21428485,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T07:09:41.480Z","updated_at":"2026-02-20T17:32:34.008Z","avatar_url":"https://github.com/miLibris.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MiLibrisReaderSDK\n\nMiLibrisReaderSDK is the new miLibris reading SDK (previously called MLPDFReaderSDK). It includes the MLFoundation library which allows unpacking miLibris contents.\n\n[CHANGELOG](./CHANGELOG.md)\n\n* [Issues](#issues)\n* [Setup](#setup)\n    * [Prerequisites](#prerequisites)\n    * [Installation via Swift Package Manager](#installation-via-swift-package-manager)\n    * [Installation via CocoaPods](#installation-via-cocoapods)\n    * [Installation via Carthage](#installation-via-carthage)\n    * [Manual installation](#manual-installation)\n    * [Migrating from MiLibrisReaderSDK v0](#migrating-from-milibrisreadersdk-v0)\n    * [Migrating from MLPDFReaderSDK v1](#migrating-from-mlpdfreadersdk-v1)\n* [Implementation](#implementation)\n    * [Usual workflow](#usual-workflow)\n    * [Download a complete archive](#download-a-complete-archive)\n    * [Extract a complete archive](#extract-a-complete-archive)\n    * [Open the reader](#open-the-reader)\n* [Optional features](#optional-features)\n    * [Configure the reader tutorial](#configure-the-reader-tutorial)\n    * [Provide an image view for transitions](#provide-an-image-view-for-transitions)\n    * [Resume reading at the last read page](#resume-reading-at-the-last-read-page)\n    * [Apply your branding to the reader UI](#apply-your-branding-to-the-reader-ui)\n    * [Support dark mode](#support-dark-mode)\n    * [Integrate with your analytics solution](#integrate-with-your-analytics-solution)\n    * [Provide article sharing functionality](#provide-article-sharing-functionality)\n    * [Provide article bookmark functionality](#provide-article-bookmark-functionality)\n    * [Customize logging](#customize-logging)\n    * [Present your own article reader](#present-your-own-article-reader)\n    * [Add a print button](#add-a-print-button)\n    * [Enable background mode for text-to-speech](#enable-background-mode-for-text-to-speech)\n    * [Configure article search](#configure-article-search)\n    * [Disable image crop in articles](#disable-image-crop-in-articles)\n    * [Customize article reader fonts](#customize-article-reader-fonts)\n\n## Issues\n\nPlease only open an issue if it concerns the usage of the reader SDK. For any other issue regarding the miLibris platform or API, contact miLibris support.\n\n## Setup\n\n### Prerequisites\n\nMiLibrisReaderSDK requires iOS 11 or later, Xcode 13 or later. The SDK is provided as a dynamic XCFramework.\n\nEvery app using the SDK must be configured with a licence key provided by miLibris. A licence key cannot be used in more than one application.\n\n- In your Xcode project, open your main target *Info.plist*\n- Add a new key named *MiLibrisReaderSDKLicenceKey* of type *String*.\n- In the value field, add the licence key provided by miLibris.\n\n### Installation via Swift Package Manager\n\n- In your Xcode project, select *File* \u003e *Swift Packages* \u003e *Add Package Dependency...*\n- In the URL field, paste *https://github.com/miLibris/ios-milibris-reader-sdk.git* and select *Next*\n- Select an update rule\n- Add the product \"MiLibrisReaderSDK\" to your app target\n\n#### Sample app\n\nAn example of an Xcode project with Swift Package Manager integration is available in this repository. To use it:\n\n- Open *sample_swiftpackagemanager/MiLibrisReaderSDKSample.xcodeproj*\n\n### Installation via CocoaPods\n\nRequires CocoaPods \u003e= 1.9\n\n- Add the following line in your *Podfile*:\n\n`pod 'MiLibrisReaderSDK', '~\u003e 1.0'`\n\n- Run `pod install`\n\n#### Sample app\n\nAn example of an Xcode project with CocoaPods integration is available in this repository. To use it:\n\n- In the *sample_cocoapods* directory, run `pod install`\n- Open *sample_cocoapods/MiLibrisReaderSDKSample.xcworkspace*\n\n### Installation via Carthage\n\nRequires Carthage \u003e= 0.38\n\n- Add the following line in your *Cartfile*:\n\n`binary \"https://raw.githubusercontent.com/miLibris/ios-milibris-reader-sdk/main/MiLibrisReaderSDK.json\" ~\u003e 1.0`\n\n- In the project directory, run `carthage update --use-xcframeworks`\n\n#### Sample app\n\nAn example of an Xcode project with Carthage integration is available in this repository. To use it:\n\n- In the *sample_carthage* directory, run `carthage update --use-xcframeworks`\n- Open *sample_carthage/MiLibrisReaderSDKSample.xcodeproj*\n\n### Manual installation\n\n- Download and unzip the SDK from the latest release: https://github.com/miLibris/ios-milibris-reader-sdk/releases/latest\n- Move *MiLibrisReaderSDK.xcframework* in your project directory.\n- Add *MiLibrisReaderSDK.xcframework* into your project's *Embedded Content* section in the project editor.\n\n#### Sample app\n\nAn example of an Xcode project with manual integration is available in this repository. To use it:\n\n- Download and unzip the SDK from the latest release: https://github.com/miLibris/ios-milibris-reader-sdk/releases/latest\n- Move *MiLibrisReaderSDK.xcframework* in *sample_manual*.\n- Open *sample_manual/MiLibrisReaderSDKSample.xcodeproj*\n\n### Migrating from MiLibrisReaderSDK v0\n\nIf using Swift Package Manager:\n\n- In your Xcode project, navigate to the project editor \u003e your project \u003e Package Dependencies\n- Double-click on the `ios-milibris-reader-sdk` package\n- Edit the version rule to *Up to Next Major 1.0.0 \u003c 2.0.0*\n\nIf using CocoaPods:\n\n- Update your Podfile with the following line:\n\n`pod 'MiLibrisReaderSDK', '~\u003e 1.0'`\n\n- Run `pod update MiLibrisReaderSDK`\n\nIf using Carthage:\n\n- Update your Cartfile with the following line:\n\n`binary \"https://raw.githubusercontent.com/miLibris/ios-milibris-reader-sdk/main/MiLibrisReaderSDK.json\" ~\u003e 1.0`\n\n- In the project directory, run `carthage update --use-xcframeworks`\n\n### Migrating from MLPDFReaderSDK v1\n\n- First remove the previous SDK from your project, depending on your installation method:\n    - Swift Package Manager: in your Xcode project editor, select your project, then select the tab \"Package dependencies\", then delete the package \"MLPDFReaderSDK\"\n    - CocoaPods: in your Podfile, remove the line `pod 'MLPDFReaderSDK'`, then run `pod install`\n    - Carthage: in your Cartfile, remove the line with `MLPDFReaderSDK`, then run `carthage update`, then remove references to the framework in your Xcode project\n    - Manual installation: delete *MLPDFReaderSDK.xcframework* from your project directory, then remove references to the framework in your Xcode project\n\n- Follow the instructions in the previous sections to install the new SDK.\n- In your Swift code, replace `import MLPDFReaderSDK` with `import MiLibrisReaderSDK`.\n- Follow the instructions in the next sections to migrate your code to use the new SDK.\n\n## Implementation\n\n⚠️ The SDK is written in Swift and is not usable from Objective-C files.\n\nThe sample projects contain working examples of the following steps.\n\n### Usual workflow\n\nIn order to read content with the SDK, your application will likely implement the following steps:\n\n- Download a complete archive (with the *.complete extension) from the miLibris platform\n- Extract the archive to a directory in the app storage\n- Open the reader to read the unpacked content\n\n### Download a complete archive\n\nRefer to the miLibris API documentation to obtain a ticket for the issue you want to download, in the `x-ml-pdf` format.\n\nYou can then download the complete archive with the following URL: `https://content.milibris.com/access/%@/download.complete` (replace `%@` with the mid of your ticket).\n\nThe JWT token returned by the API can be ignored.\n\n### Extract a complete archive\n\nA complete archive can be unpacked with the MLArchive class. This can be done as a post-download step:\n\n```swift\nimport MiLibrisReaderSDK\n\ndo {\n    // archiveURL: the file URL to the .complete file that was downloaded from the miLibris platform\n    // releaseURL: a file URL to an available directory where the content of the archive will be extracted\n    try MLArchive.extract(archiveURL, inDirectory: releaseURL)\n} catch {\n    // something went wrong: maybe there is no archive at archiveURL, maybe the releaseURL directory cannot be written...\n    print(\"Error when unpacking content: \\(error)\")\n}\n```\n\n### Open the reader\n\nOnce an archive has been downloaded and extracted, it can be opened with a few lines of code:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // Instantiate the reader\n        let reader = Reader(releasePath: releasePath, articlesLanguageCode: .frFR)\n\n        // Present it from a view controller of your app\n        reader.presentReaderViewController(from: self)\n    }\n\n}\n```\n\n## Optional features\n\n### Configure the reader tutorial\n\nThe reader is configured to display a tutorial the first time that it is opened on a new device. You can disable it you want:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController, ReaderDelegate {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.readerTutorialProvider = nil\n\n        // [...]\n    }\n\n}\n```\n\nFor testing purposes or if you have a feature that resets tutorials in your app, you can add:\n\n```swift\nimport MiLibrisReaderSDK\n\nfunc resetTutorials() {\n    MiLibrisReaderTutorialProvider().resetTutorial()\n}\n\n}\n```\n\n### Provide an image view for transitions\n\nIf you are already displaying the cover page of the issue to open in your UI, you can provide the image view to the reader in order to have nice transitions when opening or closing the reader. To do so, you must implement the reader delegate and return your image view:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController, ReaderDelegate {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.delegate = self\n\n        // [...]\n    }\n\n    // MARK: ReaderDelegate\n\n    var imageViewForReaderPresentation: UIImageView? {\n        // Provide an image view that is displaying the cover of the issue.\n        // It will be used for open and close transitions.\n        // If you return nil, a default cover transition will be used.\n        return coverImageView\n    }\n\n}\n```\n\n### Resume reading at the last read page\n\nWhen users close the reader and later open the same issue again, they might expect the reader to open at the last page that they consulted. You can implement this feature in two steps:\n\n- Implement the reader delegate to save the last page consulted by a user\n- Open the reader with the last consulted page\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController, ReaderDelegate {\n\n    private var lastSelectedPage: Int?\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.delegate = self\n        reader.initialPageNumber = lastSelectedPage ?? 1\n\n        // [...]\n    }\n\n    // MARK: ReaderDelegate\n\n    func readerViewController(_ readerViewController: UIViewController, didMoveToPageNumbers pageNumbers: [Int]) {\n        print(\"Did move to page numbers \\(pageNumbers)\")\n        lastSelectedPage = pageNumbers.first\n    }\n\n    func didDismissReaderViewController(_ readerViewController: UIViewController) {\n        // Here you can persist lastSelectedPage for later use\n    }\n\n}\n```\n\n### Apply your branding to the reader UI\n\nMany components of the reader UI can be customized to match your brand. The SDK provides a method to quickly apply your brand color and logo:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.config.applyBranding(\n            mainTintColor: .red,\n            mainTintColorComplement: .white,\n            logoImage: UIImage(named: \"myLogo\"),\n            logoBackgroundColor: .white\n        )\n\n        // [...]\n    }\n\n}\n```\n\nYou can also (or in addition to the previous method) individually customize every element of the UI. To do so, mutate the reader.config struct before opening the reader. The complete reference can be found in [Docs/config.md](./Docs/config.md#readerconfig). For example:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.config.colors.background = .red\n        reader.config.articleReader.features.isTextToSpeechEnabled = false\n\n        // Apply the same changes to all navigation bars\n        reader.config.navigationBar.applyMyConfig()\n        reader.config.summary.navigationBar.applyMyConfig()\n        reader.config.articleReader.navigationBar.applyMyConfig()\n        reader.config.articleReader.summary.navigationBar.applyMyConfig()\n\n        // [...]\n    }\n\n}\n\nextension NavigationBarConfig {\n\n    mutating func applyMyConfig() {\n        colors.titleText = .blue\n        fonts.title = .custom(UIFont(name: \"myfont\", size: 12))\n    }\n\n}\n```\n\n### Support dark mode\n\nIf your application already supports dark mode, it will also be available in the reader.\n\nIf not, you can still make it available in the reader with a few steps:\n\n- In your app's *Info.plist*, delete the line *UIUserInterfaceStyle* to opt in to dark mode support\n- In the initialization code of the root view controller of your application, disable dark mode:\n\n```swift\noverrideUserInterfaceStyle = .light // disable dark mode\n```\n\n- Every time you present a view controller modally, disable dark mode on it:\n\n```swift\nviewControllerToPresent.overrideUserInterfaceStyle = .light // disable dark mode\npresent(viewControllerToPresent, animated: true)\n```\n\n### Integrate with your analytics solution\n\nYou can register a class as a delegate to the reader. This will allow you to receive various events from the reader, that you can then send to your analytics solution:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController, ReaderDelegate {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.delegate = self\n\n        // [...]\n    }\n\n    // MARK: ReaderDelegate\n\n    func readerViewController(_ readerViewController: UIViewController, didMoveToPageNumbers pageNumbers: [Int]) {\n        print(\"Did move to page numbers \\(pageNumbers)\")\n    }\n\n    func articleReaderViewController(\n        _ articleReaderViewController: UIViewController, didOpenArticle article: ArticlePreview\n    ) {\n        print(\"Did open article \\(article.articleId): \\(article.title)\")\n    }\n\n}\n```\n\nSee the definition of `ReaderDelegate` for a complete list of events.\n\n### Provide article sharing functionality\n\nYou can provide a sharing provider to the reader in order to add a \"Share\" button on articles. Your sharing provider is responsible for providing the content to share for an article.\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.sharingProvider = MyWebsiteSharingProvider()\n\n        // [...]\n    }\n\n}\n\nclass MyWebsiteSharingProvider: SharingProvider {\n\n    func articleSharingContent(article: ArticlePreview) throws -\u003e SharingContent {\n        // You could use the miLibris article identifier or the article title to match with articles on your website\n        let url = URL(string: \"https://www.mywebsite.com/article/\\(article.articleId)\")!\n        return SharingContent(url: url, title: article.title)\n    }\n\n}\n```\n\nThe SDK also provides the implementation for sharing an article with a miLibris web kiosk.\n\n⚠️ Before implementing this protocol, contact miLibris support to make sure that the sharing feature is supported by your web kiosk.\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        let issueId = \"milibris-issue-id\" // The MID of the issue being opened, as returned by the miLibris API\n        reader.sharingProvider = MyMiLibrisSharingProvider(issueId: issueId)\n\n        // [...]\n    }\n\n}\n\nclass MyMiLibrisSharingProvider: MiLibrisWebKioskSharingProvider {\n\n    var kioskBaseURL: URL {\n        return URL(string: \"https://www.mywebkiosk.com\")!\n    }\n\n    let issueId: String\n\n    init(issueId: String) {\n        self.issueId = issueId\n    }\n\n}\n```\n\n### Provide article bookmark functionality\n\nYou can provide a bookmark provider to the reader in order to add a \"Bookmark\" button on articles. Your bookmark provider is responsible for managing the on/off state of bookmarks.\n\nThe reader does not include a list of bookmarked articles. It should be developed in your app.\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.bookmarkProvider = MyBookmarkProvider()\n\n        // [...]\n    }\n\n}\n\nclass MyBookmarkProvider: BookmarkProvider {\n\n    // In a typical application, this list is persisted somewhere\n    var bookmarkedArticlesIds = Set\u003cString\u003e()\n\n    // MARK: BookmarkProvider\n\n    func isArticleBookmarked(_ article: ArticlePreview) -\u003e Bool {\n        return bookmarkedArticlesIds.contains(article.articleId)\n    }\n\n    func setIsArticleBookmarked(\n        _ isBookmarked: Bool,\n        article: ArticlePreview,\n        from viewController: UIViewController,\n        actionSource: BookmarkActionSource\n    ) -\u003e Bool {\n        if isBookmarked {\n            bookmarkedArticlesIds.insert(article.articleId)\n            print(\"Added article to bookmarks: \\(article.title)\")\n        } else {\n            bookmarkedArticlesIds.remove(article.articleId)\n            print(\"Removed article from bookmarks: \\(article.title)\")\n        }\n\n        // Return true if the operation was successful, false otherwise.\n        return true\n    }\n\n}\n```\n\n### Customize logging\n\nBy default, the reader will print warnings and errors to the Xcode console. You can change the log level if you want to:\n\n```swift\nimport MiLibrisReaderSDK\n\nLogger.minLogLevel = .debug\n```\n\nYou can also implement logging yourself, for example to plug the reader messages to your own logging solution:\n\n```swift\nimport MiLibrisReaderSDK\n\nLogger.shared = MyLogger.self\n\nclass MyLogger: LoggerType {\n\n    static func log(_ message: String, file: String, function: String, line: Int, level: LogLevel) {\n        print(\"[MYLOGGER] \\(level.emoji) \\(message)\")\n    }\n\n}\n```\n\n### Present your own article reader\n\nIf you want to present your own article reader instead of the one provided by the SDK, you can do so using the reader delegate:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController, ReaderDelegate {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.delegate = self\n\n        // [...]\n    }\n\n    // MARK: ReaderDelegate\n\n    func readerViewController(\n        _ readerViewController: UIViewController \u0026 ArticleReaderDelegate,\n        shouldDisplayArticle article: ArticlePreview\n    ) -\u003e Bool {\n        let myArticleViewController = MyArticleViewController()\n        myArticleViewController.article = article\n        myArticleViewController.delegate = readerViewController\n        readerViewController.present(myArticleViewController, animated: true)\n        return false\n    }\n\n}\n\nclass MyArticleViewController: UIViewController {\n\n    var article: ArticlePreview?\n\n    weak var delegate: ArticleReaderDelegate?\n\n}\n\n```\n\n### Add a print button\n\nIf you want to allow users to print a single page or a double page of your publication, you can do so by updating the config:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.config.features.printEnabled = true\n\n        // [...]\n    }\n\n}\n```\n\n### Enable background mode for text-to-speech\n\nIf you want to allow the text-to-speech audio to continue while the app is in the background, you need to enable the `audio` background mode in your iOS project.\n\n- Select your project in Xcode\n- Open the \"Signing \u0026 Capabilities\" tab\n- Enable \"Background Modes\" if needed\n- Enable \"Audio, AirPlay, and Picture in Picture\"\n\n### Configure article search\n\nIf you want to add a search interface for articles in the summary, you need to configure the miLibris API access with the same keys you use in your app:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController, ReaderDelegate {\n\n    func openReader() {\n        // Instantiate the reader with the miLibris search API\n        let searchProvider = MiLibrisSearchProvider(\n            pointOfSaleMid: \"\u003cyour_point_of_sale_mid\u003e\",\n            basicAuth: \"\u003cyour_basic_auth\u003e\",\n            issueMid: \"\u003cissue_mid_being_opened\u003e\"\n        )\n        let reader = Reader(\n            releasePath: releasePath, articlesLanguageCode: .frFR, searchProvider: searchProvider\n        )\n\n        // [...]\n    }\n\n}\n```\n\n### Disable image crop in articles\n\nBy default some images in articles are cropped to better fit the templates. If you want to disable all image cropping you can add the following configuration:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        reader.config.articleReader.features.forceLayout = .default\n        reader.config.articleReader.features.isImageCropEnabled = false\n\n        // [...]\n    }\n\n}\n```\n\n### Customize article reader fonts\n\nYou can quickly customize the article reader fonts to match your brand:\n\n```swift\nimport MiLibrisReaderSDK\n\nclass MyViewController: UIViewController {\n\n    func openReader() {\n        // [...]\n\n        // Set this before presenting the reader\n        try reader.config.articleReader.articleReader.applyPrimaryFont(\n            regularFontName: \"PlayfairDisplay-Regular\",\n            blackFontName: \"PlayfairDisplay-Black\",\n            boldFontName: \"PlayfairDisplay-Bold\"\n        )\n        try reader.config.articleReader.applySecondaryFont(\n            regularFontName: \"ComicNeue-Regular\",\n            mediumFontName: \"ComicNeue-Light\",\n            semiBoldFontName: \"ComicNeue-Bold\"\n        )\n        try reader.config.articleReader.applyTertiaryFont(\n            regularFontName: \"RobotoCondensed-Regular\",\n            blackFontName: \"RobotoCondensed-Black\",\n            boldFontName: \"RobotoCondensed-ExtraBold\",\n            italicFontName: \"RobotoCondensed-Italic\"\n        )\n\n        // [...]\n    }\n\n}\n```\n\nSee the methods documentation in code for more info. In addition to this, you can also customize each UI component individually with the corresponding config properties.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilibris%2Fios-milibris-reader-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmilibris%2Fios-milibris-reader-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilibris%2Fios-milibris-reader-sdk/lists"}