Auth API is available via account
property of PressReader
. Normally Host app performs PressReader authorization on start or before access to PressReader
features is required.
let account = PressReader.instance().account
account.authorize(token: String, completion: Callback)
Authorization by service name allows working with SDK based on service name only, without token. In order to achieve this behavior the next configuration has to be done:
In Info.plist
of your app add PRConfig
dictionary with SERVICE_NAME
string type entry with your service name value.
To observer SDK's current state utilize the state
property:
PressReader.instance().state
SDK state
is described by the following options:
typedef NS_OPTIONS(NSUInteger, PRState) {
PRStateRunning = 1 << PRStateTypeRunning,
PRStateActivated = 1 << PRStateTypeActivated,
PRStateCatalogLoaded = 1 << PRStateTypeCatalogLoaded
};
Each change in the state triggers the PressReaderStateDidChange
notification. Alternatively, employ the PressReaderState
class to manage state using the Combine API.
SDK state
has to turn .activated
to execute any operations and .catalogLoaded
to be able to download issues.
After the instance of PressReader SDK is authorized the issues downloading becomes possible. The downloading process is manageable via catalog item's download property that conforms to Download interface described below.
Download {
var state: DownloadState
var progress: Int
var error: Error?
func start()
func pause()
func cancel()
}
where DownloadState
is
enum DownloadState {
stop, // the downloading wasn’t started or was stopped due to error
progress, // the downloading is in progress
pause, // the downloading is paused
ready // downloading was successfully completed
}
You access specific download for a cid
/ date
pair via corresponding item in catalog:
guard let download = PressReader.instance().catalog.item(cid, date)?.download else {
print("Item with given cid / date isn't found")
return
}
download.start()
download.pause()
To resume download call download.start()
method again.
download.cancel()
Downloading state and progress can be accessed via state
, progress
and error
properties.
Additionally download
object conforms to observation interface that allows to attach handlers to follow download progress in real time.
Download {
/// when the returned DownloadObserver is deinited it will stop observing
func observe(_ callback: @escaping Callback) -> DownloadObserver?
}
where Callback
is
typealias Callback = (DownloadState, Progress, Error?) -> Void
AuthorizationError
is returned when there’s a problem with authorization and re-authorization is required.
if let reader = ReadingVC(issue: issue) {
yourViewController.present(reader. animated: true, completion: nil)
}
reader
can be nil in case issue hasn't been previously ordered (dowload process not started)
The management of downloaded catalog items can be done via downloaded
property of catalog
let downloaded = PressReader.instance.catalog.downloaded
where downloaded
is
Downloaded {
// returns the list of downloaded items
var items: [Item]
// deletes downloaded item
func delete(_ item: Item)
func deleteAll()
}
where Item
is
Item {
var cid: String
var date: Date
var title: String
var size: Long?
var download: Download
}
Please check Download section for the information how to access the item's download state and open it.
Downloaded
object conforms to the observation interface and “calls back” on items deletion or insertion.
Downloaded {
/// when the returned Observer is deinited it will stop observing
func observe(_ callback: @escaping ()->()) -> Observer
}
The getLogs
asyncronous method is available to collect device logs and upload to server
func getLogs(completion: (Result<(linkToUploadedLogs: URL, additionalInfo: String), Error>) -> Void)
completion
is a callback executed after obtaining all required information including linkToUploadedLogs, additionalInfo - some textual information we usually provide along with logs inside feedback email, like OS version, device model, device id, some internal component versions (SDK version) and crash stack if available.
A list of tracker classes can be passed to PressReader SDK init method to track events happening when publication is viewed:
var trackerList: MutableList<AnalyticsTracker> = ArrayList()
trackerList.add(CustomTracker())
PressReader.init(Application.this, PressReader.Params(trackerList))
where CustomTracker
inherits from ReadingViewAnalyticsTracker
and overrides the methods corresponding to the events to be logged.
Event name | Event parameters | Description |
---|---|---|
OpenIssueForReading |
issue |
Publication issue opened for reading |
IssuePage |
issue ,pageNumber |
Issue page is changed (reading view) |
IssueTextFlow |
issue |
Issue article feed is presented (text view) |
ArticleView |
article |
Full Article Text view presented |
Translated |
fromLanguage ,toLanguage |
Translated article presented |
ListenView |
issue |
text-to-speach view presented |
where fromLanguage
, toLanguage
are ISO language codes,
Any host app’s provided tracker should conform to abstract AnalyticsTracker
protocol with no methods defined, but all protocol for different part of tracking functionality would include this protocol, for example the only currently defined RreadingViewAnalyticsTracker
protocol:
public protocol ReadingViewAnalyticsTracker: AnalyticsTrackerProtocol {
/// publication opened for reading
func trackOpenIssueForReading(issue: TrackingIssue)
/// reading(replica) view switched to pageNumber [1...N]
func trackIssuePage(issue: TrackingIssue, pageNumber: Int)
/// reading view switched to text flow of article snippets (phone only)
func trackIssueTextFlow(issue: TrackingIssue)
/// reading view switched to detail article view
func trackArticleView(issue: TrackingIssue, article: TrackingArticle)
/// presenting "newspaper radio view" initiated from replica or article view
func trackListenView(issue: TrackingIssue)
/// presenting translated version of article, languages parameter are alpha-2 ISO codes
func trackTranlated(article: TrackingArticle, languageFrom: String, laguageTo: String)
/// specific page printed from replica view (full page or cropped to visible part)
func trackPrintedPages(issue: TrackingIssue, isFullPage: Bool, pageNumbers: [Int])
/// article printed as a formatted text or as it presented in replica view
func trackPrintedArticle(issue: TrackingIssue, article: TrackingArticle, inReplicaPresentation: Bool)
}
Protocol methods are all have default implementation doing nothing, so host app implementation should only defined those methods in their classes which they want to track for example:
extension SomeTracker: ReadingViewAnalyticsTracker {
func trackOpenIssueForReading(issue: TrackingIssue) {
print ("Openin publication \(issue.slug) of \(issue.date) opened for reading")
}
}
The following public API structures defined for host developer to be used inside ReadingViewAnalytics protocol methods as parameters:
public struct TrackingIssue {
public let cid: String
public let date: Date
public let isLatest: Bool
public let version: Int?
public let smartLayoutVersion: Int?
public let title: String
public let slug: String?
public let sourceType: String // currently "newspaper" or "magazine"
}
public struct TrackingArticle {
public let id: String
public let headline: String
public let language: String
}
providing most of possibly used for analytics information from both replica and article view. In the future we’ll define more protocols for analytics in other parts of the tracked functionality.
Because PressReader
class is a singleton, the host app should setup the list of analytics trackers via launchOptions class property before first use of PressReader
:
private lazy var pressreader: PressReader = {
PressReader.launchOptions = [.prAnalyticsTrackers: [self]]
return PressReader.instance()
} ()