Support libraries which enable easier development of iOS applications that work with Alfresco products.
The libraries are available as independent frameworks via Cocoapods.
Head over to project folder, create a pod file by issuing pod init
into the terminal, edit it and add the following:
source 'https://cdn.cocoapods.org/'
followed by your desired pod configuration.
E.g. :
pod 'AlfrescoAuth'
pod 'AlfrescoContent'
For more details on how to set up Cocoapods, please refer to the official documentation.
We use semantic versioning when publishing our libraries. You can read more about it here.
The libraries require iOS 12+ and Swift 5+.
Easiest way to get off the ground is to check the included Sample App.
The sample shows how to get authentication working with the identity service, and how to integrate that with the API bindings to get a first request going.
The app should just work with your identity service install, but might not match your current configuration so edit AuthenticationParameters.swift if you run into any issues.
The auth module offers several abstractions to work with the Alfresco Identity Service and Basic Authentication.
For basic authentication build your own UI to collect credentials. There isn't much to provide to the library but you could take advantage of some of the constructs we've been using in the sample app.
For SSO your activity will have to present the user a WebView for him to login and then collect the token at the end.
Several steps are required to make it work.
Note that this step is optional as it might have been taken care of by your administrator.
First, you need to define a client within Identity service that would serve the mobile apps. Access Keycloak admin interface and navigate to the Clients page. Add a new client entry and note down the client ID value. Save the entry and on the next page, search for the Valid Redirect URIs
field. The value for this particular field should be in the following format clientID://custom-domain-name/auth
.
It's important that the redirect URI that was set is mirrored in the settings of the mobile client as well. To do so, open up the Info.plist
file of your project, and add the following structure:
- Add a 'URL types' key of type Array
- As a child dependency for 'URL types' add a new key of type Dictionary
- As a child dependency of the former item, add a 'URL Schemes' key of type String with the value of the previously set redirect URI.
Note that this step is optional as it might have been taken care of by your administrator.
First, you need to define a client within Auth0 that would serve the mobile apps. Access the Auth0 admin interface and navigate to the Clients page. Add a new client entry and note down the client ID value. Save the entry and, on the next page, search for the Valid Redirect URIs
field. The value for this particular field should be in the following format {Bundle_Identifier}://{Your_Domain}/ios/{Bundle_Identifier}/callback
.
It's important that the redirect URI that was set is mirrored in the settings of the mobile client as well. To do so, open up the Info.plist
file of your project, and add the following structure:
- Add a 'Domain' key of type String
- Add a 'ClientId' key of type String
For more information, please refer to our sample app.
First, your view model will have to initialize the auth module with your configuration and call the authentication method. The configuration object needs to match your configuration in Identity Service.
class MyLoginViewModel {
init() {
alfrescoAuth = AlfrescoAuth.init(configuration: authConfig)
}
...
}
Next call the pkceAuth method on the auth module passing in the view controller where you want to show the SSO Webview and delegate class where to receive the updates.
class MyLoginViewModel {
func login(in viewController: UIViewController) {
alfrescoAuth.pkceAuth(onViewController: viewController, delegate: self)
}
}
extension MyLoginViewModel: AlfrescoAuthDelegate {
func didReceive(result: Result<AlfrescoCredential, APIError>, session: AlfrescoAuthSession?) {
switch result {
case.success(let credential):
// Store credential and session object
...
case .failure(let error):
...
}
}
Upon successful login the server will callback with your token using the callback URI in your Info.plist
.
The authorization response URL is returned to the app via the - (**BOOL**)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, **id**> *)options
app delegate method so you need to pipe this through the current authorization session.
On the AlfrescoSession
object call the resumeExternalUserAgentFlow
method and forward the URL provided by the openURL method.
You can check out our sample app to see a way of handling this.
Because authentication is an independent step we strongly recommend you do extra validation after didReceive before letting the user into the app.
Things you could check at this time, could be profile information or permissions, which would require calling the Alfresco service and thus verifying your authentication session is working correctly.
Depending of the desired mode of authentication, the session object might need to be kept alive in the object graph. This is valid for the PKCE mode of authentication.
Upon authentication, the AlfrescoAuth module will provide an AlfrescoSession
object that should be referenced for the timespan of the session is active. This is the only object that you need to serialize to retain the authorization state.
While normally you could just destroy the persisted credentials, in case of SSO the session needs to be invalidated or the user will log back in without a credentials prompt.
To do so, just call the logout method on the AlfrescoAuth module providing the last set of credentials you have for the user.
class MyLoginViewModel {
func logOut(onViewController viewController: UIViewController, lastKnownCredential: AlfrescoCredential, delegate: AlfrescoAuthDelegate) {
alfrescoAuth.logout(onViewController: viewController, delegate: self, forCredential: lastKnownCredential)
}
}
extension MyLoginViewModel: AlfrescoAuthDelegate {
func didLogOut(result: Result<Int, APIError>) {
...
}
}
In the case of SSO the refresh token might expire or a remote actor might invalidate the user's session in the Identity Service.
Even in the Basic Authentication scenario this may happen if the password gets changed.
When this happens we recommend you prompt the user that he'll have to re-login.
While for Basic Authentication it's up to you to figure out the integration, for SSO there is a special re-authentication flow.
class MyLoginViewModel {
func refreshSession(delegate: AlfrescoAuthDelegate) {
// The session object is the same one provided after the successfull log in
if let session = self.session {
alfrescoAuth.pkceRefresh(session: session, delegate: self)
}
}
}
On success the new session will be returned again via didReceive(result:, session:)
and after updating the stored credentials you can let the user resume their activities.
The content module provides API bindings to be used with Alfresco Content Services
The module includes bindings for both search and core to make it easier to integrate in most applications.
To start using the module you will first need to import it in your business logic layer then set the basePath
static property to point to the correct instance of Alfresco.
Additionally, you should provide a credential set which you could either attach as part of the customHeaders
property or use the credential: URLCredential?
property.
Now just get a service and make your request:
class RecentsViewModel {
func fetchRecentsList() {
AlfrescoContentAPI.customHeaders = ["Authorization": authorizationHeaderValue()]
SearchAPI.search(queryBody:"my querry", ...) {
if let entries = result?.list?.entries {
// handle results
}
}
}
}
For more information on the APIs just read our documentation
We'd love to accept your patches and contributions to this project.
All external submissions require formal review. We use GitHub pull requests for this purpose. Consult GitHub Help for more information on using pull requests.