Code Monkey home page Code Monkey logo

matrix-ios-kit's Introduction

Deprecated

The MatrixKit will no longer be supported, the code will be merged into Element iOS repository.

Please avoid to create issues or PR in this repository, report them to Element iOS instead.

MatrixKit

While MatrixSDK provides an Objective-C API to use the Matrix Client-Server API, MatrixKit provides a higher level, reusable and easy-customisable UI built on top of the SDK.

Put simply, MatrixKit is a set of ViewControllers and Views. An app developer can pick up UI components from this set and insert them into their application storyboard or code. The end application controls what is shown when.

Each of the provided UI components has been designed to run standalone. There are no dependencies between them.

The currently available view controllers are:

  • MXKRoomViewController: shows messages of a room and allows user to chat
  • MXKRecentListViewController: displays the user's rooms ordered by last activity
  • MXKRoomMemberListViewController: a page showing the list of a room's members

Coming soon:

  • Authentication views
  • Public rooms: the list of public rooms
  • Room creation
  • Address book

Screenshots

Here are two samples for displaying messages of a room:

https://raw.githubusercontent.com/matrix-org/matrix-ios-kit/develop/Screenshots/MXKRoomViewController-w240.jpeg https://raw.githubusercontent.com/matrix-org/matrix-ios-kit/develop/Screenshots/MXKJSQMessagesViewController-w240.jpeg

The left one is the stock room view controller. This is the one used by Console (GitHub).

The right one is an override of JSQMessagesViewController. The display is fully managed by JSQMessagesViewController but the implementation uses data computed by MatrixKit components: MXKRoomDataSource & MXKRoomBubbleCellData. See the next session for definition of DataSource and celldata.

Overview

All view controllers in MatrixKit that display a list of items share the same ecosystem based on 4 components:

ViewController
The ViewController is responsible for managing the display and user actions.
DataSource

Provides the ViewController with items (CellView objects) to display. More accurately, the DataSource gets data (mainly Matrix events) from the Matrix SDK. It asks CellData objects to process the data into human readable text and store it. Then, when the ViewController asks for a cellview, it renders the corresponding CellData into a cellview that it returns.

For convenience, DataSources provided in MatrixKit implement UITableViewDataSource and UICollectionViewDataSource protocols so that UITableView and UICollectionView DataSources can be directly plugged to them.

CellData
Contains data the CellView must display. There is one CellData object per item in the list. This is also a kind of cache to avoid displayed data needing to be computed everytime.
CellView
This is an abstract object. It is often a UITableViewCellView or a UICollectionViewCell but can be any UIView. This is the view for an item displayed by the ViewController.

How to use it in your app

Installation

You can embed MatrixKit to your application project with CocoaPods. The pod for the latest MatrixKit release is:

pod 'MatrixKit'

Use case #1: Display a screen to chat in a room

Suppose you have a MXSession instance stored in mxSession (you can learn how to get in the Matrix SDK tutorials here ) and you want to chat in #matrix:matrix.org which room id is !cURbafjkfsMDVwdRDQ:matrix.org.

You will have to instantiate a MXKRoomViewController and attach a MXKRoomDataSource object to it. This object that will manage the room data. This is done with the following code:

// Create a data souce for managing data for the targeted room
MXKRoomDataSource *roomDataSource = [[MXKRoomDataSource alloc] initWithRoomId:@"!cURbafjkfsMDVwdRDQ:matrix.org" andMatrixSession:mxSession];

// Create the room view controller that will display it
MXKRoomViewController *roomViewController = [[MXKRoomViewController alloc] init];
[roomViewController displayRoom:roomDataSource];

Then, your app presents roomViewController. Your end user is now able to post messages or images to the room, navigate in the history, etc.

Use case #2: Display list of user's rooms

The approach is similar to the previous use case. You need to create a data source and pass it to the view controller:

// Create a data source for managing data
MXKRecentsDataSource *recentsDataSource = [[MXKRecentsDataSource alloc] initWithMatrixSession:mxSession];

// Create the view controller that will display it
MXKRecentListViewController *recentListViewController = [[MXKRecentListViewController alloc] init];
[recentListViewController displayList:recentsDataSource];

Customisation

The kit has been designed so that developers can make customisations at different levels, which are:

ViewController
The provided ViewControllers can be subclassed in order to customise the following points:
  • the CellView class used by the DataSource to render CellData.
  • the layout of the table or the collection view.
  • the interactions with the end user.
CellView
The developer may override MatrixKit CellViews to completely change the way items are displayed. Note that CellView classes must be conformed to the MXKCellRendering protocol.
CellData
The developer can implement his own CellData classes in order to prepare differently rendered data. Note that the use of customised CellData classes is handled at DataSource level (see registerCellDataClass method).
DataSource
This object gets the data from the Matrix SDK and serves it to the view controller via CellView and CellData objects. You can override the default DataSource to have a different behaviour.

Customisation example

Use case #1: Change cells in the room chat

This use case shows how to make cellView customisation.

A room chat is basically a list of items where each item represents a message (or a set of messages if they are grouped by sender). In the code, these items are inherit from MXKTableViewCell. If you are not happy with the default ones used by MXKRoomViewController and MXKRoomDataSource, you can change them by overriding MXKDataSourceDelegate methods in your view controller:

- (Class<MXKCellRendering>)cellViewClassForCellData:(MXKCellData*)cellData
{
   // Let `MyOwnBubbleTableViewCell` class manage the display of message cells
   // This class must inherit from UITableViewCell and must conform the `MXKCellRendering` protocol
   return MyOwnBubbleTableViewCell.class;
}

- (NSString *)cellReuseIdentifierForCellData:(MXKCellData*)cellData
{
    // Return the `MyOwnBubbleTableViewCell` cell identifier.
    return @"MyOwnBubbleTableViewCellIdentifier";
}

You may return a cellView class by taking into account the provided cell data. For example you can define different classes for received and sent messages.

Development

If you want to help to improve MatrixKit by adding new ViewControllers, new views, new CellViews or other improvements, this git repository contains a sample Xcode project for demoing all reusable UI. Please hack on the develop branch and make git pull requests from it.

As its dependencies are based on CocoaPods, you will need to run pod install before opening MatrixKit.xcworkspace.

Attributions

The filled icons play, pause, minus, back and keyboard are taken from icons8: http://icons8.com/

Copyright & License

Copyright (c) 2014-2017 OpenMarket Ltd Copyright (c) 2017 Vector Creations Ltd Copyright (c) 2017-2018 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

matrix-ios-kit's People

Contributors

a22sc avatar alisoftware avatar aramsargsyan avatar barpaw avatar crystal-rainslide avatar dbkr avatar gileluard avatar giomfo avatar ihorhordiichuk avatar ismailgulek avatar jelv avatar krombel avatar langleyd avatar linagkar avatar manuroe avatar morozkin avatar nvbln avatar osoitz avatar pixlwave avatar riottranslatebot avatar sbiosoftwhare avatar spantaleev avatar stefanceriu avatar szimszon avatar t1011 avatar thibaultamartin avatar thoraj avatar ujdhesa avatar weblate avatar ylecollen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

matrix-ios-kit's Issues

Three 'error build: Undefined symbol' errors and the project isn't buildable with the newest XCode version on M1 macbook

Describe the bug
After updating the XCode to the newest version the project is not buildable due to the following errors:

  • error build: Undefined symbol: _AFNetworkingReachabilityDidChangeNotification
  • error build: Undefined symbol: _AFNetworkingReachabilityNotificationStatusItem
  • error build: Undefined symbol: OBJC_CLASS$_AFNetworkReachabilityManager

To Reproduce
I have MatrixKit as a dependency in the project and build it with the newest XCode Version 14.0 (14A309) on M1 MacBook Pro.

Expected behavior
The project should be buildable

Screenshots
Screenshot 2022-09-13 at 12 09 41

The following Swift pods cannot yet be integrated as static libraries

Using the command 'pod 'MatrixKit' appears "the Swift pod MatrixKit depends upon MatrixSDK, HPGrowingTextView, libPhoneNumber-iOS, DTCoreText, and cmark, which do not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set use_modular_headers! globally in your Podfile, or specify :modular_headers => true for particular dependencies. "

duplicate messages when sending - local echo not removed

I'm seeing duplicate messages when sending from MXKRoomViewController. It seems these are "local echo" messages, which are supposed to be removed after the message sent to the server.

In -[MXKRoomDataSource refreshEventListeners:] - the event listener is created. It checks if there are outgoing messages, and then attempts to find the local echo.

MXEvent *localEcho;
if (self.room.outgoingMessages.count && [event.sender isEqualToString:self.mxSession.myUser.userId])
{
    localEcho = [self.room pendingLocalEchoRelatedToEvent:event];

Two problems: room.outgoingMessages.count is zero. But even if that check is removed, pendingLocalEchoRelatedToEvent: returns nil.

The two messages in the room are almost identical - so i'm not sure how the matrix kit or matrix sdk is supposed to reliably detect the local echo. For example:

{
  "origin_server_ts" : 1597651389299,
  "sender" : "@user1:xxx.org",
  "content" : {
    "msgtype" : "m.text",
    "body" : "Echo?"
  },
  "type" : "m.room.message",
  "event_id" : "$pdATtqY6beNczJlxfpAnk1DbW8k8l9ycTHeeNdij-_0",
  "room_id" : "!rytTykSOlVDqLRpOkK:xxx.org"
}
{
  "sender" : "@user1:xxx.org",
  "content" : {
    "msgtype" : "m.text",
    "body" : "Echo?"
  },
  "origin_server_ts" : 1597651385012,
  "room_id" : "!rytTykSOlVDqLRpOkK:xxx.org",
  "event_id" : "$pdATtqY6beNczJlxfpAnk1DbW8k8l9ycTHeeNdij-_0",
  "unsigned" : {
    "age" : 56854,
    "transaction_id" : "kMXEventLocalId_3AEC3166-F36C-495C-A048-A5FB5D436B56-96982-00019D04955033FC"
  },
  "type" : "m.room.message"
}

Anyone have any thoughts on why the local echo detection might be failing? Any workarounds? This issue happens consistently for me (and I'm not doing anything weird).

Delete messages/conversations for one user without leaving room or redacting messages

I am using MatrixKit to create an iOS application that allows users to privately message each other. Is it possible to delete a conversation locally for just one user without leaving the room? I want users to be able to delete conversations from their own accounts without leaving the room (which would cause the other member to see an "Empty Room" message). Furthermore, if they create a new conversation with the same user after deleting the conversation, the other user should see all of the message history, but the user that deleted that history shouldn't.

Store Messages And Rooms and offer Offline experience

Hello. We want to offer offline experience and we use the MXFileStore in the app delegate:

...
// Prepare account manager
MXKAccountManager *accountManager = [MXKAccountManager sharedManager];
    
// Use MXFileStore as MXStore to permanently store events.
accountManager.storeClass = [MXFileStore class];

 [accountManager prepareSessionForActiveAccounts];
....

Then to load the recents we use this code:

// Create a data source for managing data
MXKRecentsDataSource *recentsDataSource = [[MXKRecentsDataSource alloc] initWithMatrixSession:mxSession];

// Create the view controller that will display it
MXKRecentListViewController *recentListViewController = [[MXKRecentListViewController alloc] init];
[recentListViewController displayList:recentsDataSource];

But without internet connection any room is shown... Why?

P.S. The session comes form the AccountManager.shared.account.first.mxSession

Wrong bubble layout after an image redaction

Image thumbnail is correctly replaced by redact message in chat room but associated bubble is not resizing to match text message size.

We need to exit chat room and enter again to see redact message displayed in a bubble with correct size.

[MXKRoomDataSource] Warning: The user does not know the room XXX

Describe the bug
By following the MatrixSDK use case 4, I can post a text message to a room.
But by following the MatrixKit use case 1, an error occurred "[MXKRoomDataSource] Warning: The user does not know the room XXX".

To Reproduce

MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:SESSION];
MXKRoomViewController *roomViewController = [[MXKRoomViewController alloc] init];

[roomDataSourceManager roomDataSourceForRoom:ROOM_ID create:YES onComplete:^(MXKRoomDataSource *roomDataSource) {
    [roomViewController displayRoom:roomDataSource];
    [UIApp.keyWindow.rootViewController presentViewController:roomViewController animated:YES completion:nil];
}];

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: iPad mini 4
  • OS: iOS14.0
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Italian translation added in Weblate

Hi to all. A few days ago I added it here, then I opened this issue under vector-im/riot-ios to ask how to have it merged into their work, but I haven't received any reply yet. Thus I'm posting this to ask for the right way to add this contribution: I'd like this language to be supported by iOS Matrix clients ASAP.

Thanks.

nil image from UIImagePicker url

When selecting and sending an image, I'm finding that I'm unable to load the selected image (into NSData). The dict returned by the UIImagePIcker contains all the expected keys/values, but using [NSData dataWithContentsOfFile:imageLocalURL.path]; only results in nil.

I've added the plist value to access the photo library: NSPhotoLibraryUsageDescription

Does this image picker code need to be updated to use PhotoKit?

// from: MXKRoomInputToolbarView.m
NSURL *imageLocalURL = [info objectForKey:UIImagePickerControllerReferenceURL];
if (imageLocalURL)
{
   CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[imageLocalURL.path pathExtension] , NULL);
   NSString *mimetype = (__bridge_transfer NSString *) UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType);
   CFRelease(uti);
   
   NSData *imageData = [NSData dataWithContentsOfFile:imageLocalURL.path]; // nil!

Allow users to search in encrypted rooms with local data

  • Search is now available only for unencrypted rooms, and not available for encrypted rooms.
  • Search can be enabled for encrypted rooms by searching from locally cached datas.
  • For now the search can work within locally available data, and may be enhanced to efficiently load the entire history on users need.

Rethink MXKImageView: Improve performance and make it more specific

MXKImageView is used for many cases, from displaying image in full screen to display read receipts avatars.
For example UIScrollView allocation in �initLayout method� is time consuming and not needed for most cases like avatar display.
I/O operations and network calls are also made on main thread.
Those issues slow down UI.

We should at least:

  • Perform I/O operations and network calls in background
  • Use a separate viewer for displaying images in full screen

Add New Message Type

Hello.

We want to add a new message type. How can we do it in the best way?
We are also interested in storing later this custom message type in the MXFileStore to offer the offline experience.

Thanks

MXKAccountManager: accounts are stored in a discardable cache files when no app group id is available

When no application group identifier is defined, the Matrix account credentials are stored in a discardable cache files (Library/Caches).

Indeed the [MXKAppSettings cacheFolder] used in MXKAccountManager:

NSString *matrixKitCacheFolder = [MXKAppSettings cacheFolder];
returns this folder when no group id is defined, see:
NSArray *cacheDirList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);

A new method should be added to MXKAppSettings to return an applicationSupportFolder (based on NSApplicationSupportDirectory), then the MXKAccountManager will be able to use it to store account data (when no group id is defined).

Create separate projects for MatrixKit library and MatrixKit code sample

It will allow to decouple sample code from MatrixKit code and use specific project configurations for each projects.
And it will be an opportunity to have a target named MatrixKit that will allow to use Swift code in Objective-C easily without renaming Product Module Name build setting of current MatrixKitSample target.
Indeed in order to use Swift code in Objective-C inside MatrixKit framework we need to import <ProductModuleName>-Swift.h in Objective-C implementation files (.m). As Product Module Name is currently MatrixKitSample in MatrixKit project and generated pod project has MatrixKit as Product Module Name it could not compile for both cases without renaming the Product Module Name.

The http(s)LinkScheme setting is too simplistic

The MXKAppSetting properties httpLinkScheme and httpsLinkScheme allow for the use of a third-party browser to open links. This works great for Chrome but not for Firefox which expects a URL of the form firefox://open-url?url=encodedUrl where encodedUrl is the target url encoded as query param (this is done by addingPercentEncoding(withAllowedCharacters: urlQueryAllowed).

This can become quite complex (as is at Telegram) because some browser expect a format like dolphin://http://whatever.com or yandexbrowser-open-url://escapedUrl where escapedUrl is url-host escaped.

While I think, the latter stuff is unneeded, the support for Firefox would be nice and is also asked for at Riot. I will work on this.

[MXKAccountManager] Handle UserNotifications framework API when checking local notifications settings

-[MXKAccountManager isPushAvailable] should now handle iOS 10 UserNotifications framework to check if local notifications are enabled.

The problem is that with the UserNotifications framework the notification settings are available only asynchronously with [UNUserNotificationCenter getNotificationSettingsWithCompletionHandler:] method.

So isPushAvailable should evolve to be asynchronous now.

Note, it could also be great to:

  • have a LocalNotificationService and RemoteNotificationService to decouple complexity
  • avoid handling push notification from MXKAccount.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.