Build an API-backed table in minutes, right from Interface Builder!
Example: Chatting app
API URL: https://api.abstractlayer.com/demo/silicon_valley/get_users
Click the arrow to check out the full JSON response
<pre><code>[
{ "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/richard-hendricks.jpg", "timestamp": 1491631526, "last_message": "Thank god they use tabs!", "name": "Richard Hendricks", "id": "5925b5ac22f9a51d0ca5a3ce" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/guilfoyle.jpg", "timestamp": 1491639798, "last_message": "This framework is better than hell.", "name": "Guilfoyle", "id": "5925b5ac58cff049f195e566" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/dinesh.jpg", "timestamp": 1491633121, "last_message": "I can’t believe Guilfoyle actually loved something other than himself.", "name": "Dinesh", "id": "5925b5ac71aef5f0f3febd4a" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/jared.jpg", "timestamp": 1491634194, "last_message": "Based on my SWOT analysis, this framework is a great investment.", "name": "Jared", "id": "5925b5ac6af1272071a57d72" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/jian-yang.jpg", "timestamp": 1491634511, "last_message": "This is not a hotdog.", "name": "Jian Yang", "id": "5925b5acdfecdab484513b96" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/erlic-bachman.jpg", "timestamp": 1491642125, "last_message": "Abstract Layer is the intersection of spirituality and automation.", "name": "Erlic Bachman", "id": "5925b5acec7ff952f35a65eb" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/laurie-bream.jpg", "timestamp": 1491633389, "last_message": "Is Abstract Layer raising?", "name": "Laurie Bream", "id": "5925b5ac9b66bc12c486cdfb" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/gavin-belson.jpg", "timestamp": 1491641044, "last_message": "Why again did Hooli not build this framework?", "name": "Gavin Belson", "id": "5925b5acff14642da4571ef2" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/russ-hanneman.jpg", "timestamp": 1491630862, "last_message": "This framework f*cks!", "name": "Russ Hanneman", "id": "5925b5ac42c8cdfb0c17664d" }, { "image_url": "http://docs.abstractlayer.com/demo/table-view/silicon-valley/images/big-head.jpg", "timestamp": 1491639079, "last_message": "Woah this Abstract Layer thing is awesome!!", "name": "Big Head", "id": "5925b5ac29f5b9e382590e1a" } ]
If you haven't already added the framework to your Xcode project, follow this tutorial.
-
Open
Main.storyboard
and delete the default view controller -
Drag an instance of
UITableViewController
From the menu bar choose:
Editor → Embed in → Navigation Controller
- Click on your navigation controller then check the box that says
Is initial View Controller
from the Attributes Inspector
-
Click on your prototype cell, and set the
cell identifier
tocell
in the Attributes Inspector -
Drag the prototype cell in your storyboard from the bottom to increase its
height to 80
-
Design the tableview's cell to match the design
UIImageView
for the user image (size 50x50)UILabel
for the name label (Font size 13, semibold, black)UILabel
for the last message label (Font size 12, regular, dark gray)UILabel
for the date label (Font size 12, regular, light gray)
-
Choose
2 lines
for last message label
It's time to bind data between the JSON document and the UI elements.
-
Open the URL in a browser https://api.abstractlayer.com/demo/silicon_valley/get_users
-
Copy the URL
-
Go to your storyboard and click on your
UITableView
and change its class toALTableView
in the Identity Inspector
-
Navigate to your Attributes Inspector, and you'll find a list of new attributes
-
Paste the URL you just copied in the new
Url
field -
Type in
GET
for HTTP method
Your table view is now ready to process the API. It's time to match the JSON keys with the UI elements to fill the data automatically.
User Image
- Click on your
UIImageView
and change its class toALImageView
in the Identity Inspector
- Type in
image_url
in theJson Key
field so that Abstract Layer can automatically load the image using its URL value
Circular Image
To get a circular user image, turn the circular
option ON
.
Name Label
- Click on the name label and change its class to
ALLabel
in the Identity Inspector
- Type in
name
in theJson Key
field to automatically match the JSON value with the name label
Last Message Label
-
Click on the last message label and change its class to
ALLabel
in the Attributes Inspector -
Type in
last_message
in theJson Key
field
Date Label
- Click on the date label and change its class to
ALDateLabel
in the Attributes Inspector
-
Type in
timestamp
in theJson Key
field -
Type in
MM/dd/yyyy
in theOutput Format
field to get the desired date format displayed.
The format should abide by Apple's DateFormatter rules
Handle any kind of error by checking the Error handling section
Run the project, and there you go! MAGIC!
This looks great so far, but we're sure you've got many questions about how far can Abstract Layer go.
Error Handling Handle all kind of errors when loading your table view |
Passing Data You have FULL access to parsed data, so passing it is very simple |
Parameters Be it Header or Body, Static or Dynamic, it's all in Interface Builder |
Pagination Enabling pagination takes less than a minute |
Complex JSON Any form of JSON is supported, no matter how complex it is |
Loader Enable loaders and pull-to-refresh with 2 clicks |
The example below shows how you can fully customize the table view example by modifying the parsed data before displaying it.
Remember: ALTableView is a subclass of UITableView
Remember: You have FULL access to the data parsed by accessing the array property on your Table view
- Create a new class, call it
CustomTableViewCell
- Set the Table view cell class to
CustomTableViewCell
-
Control-drag your date label to the class as a new outlet and call it
dateLabel
-
Don't forget to import
AbstractLayer
to the class's header
- Create a new class, call it
TableViewController
and subclass it formUITableViewController
- Set your table view class in storyboard to
TableViewController
- Replace the content of the class with the following:
import UIKit import AbstractLayer
class TableViewController: UITableViewController {
// // MARK: Lazy load // private lazy var today:Double = { var calendar = NSCalendar.current calendar.timeZone = NSTimeZone(abbreviation: "UTC")! as TimeZone return calendar.startOfDay(for: Date()).timeIntervalSince1970 }()
private lazy var yesterday:Double = { var calendar = NSCalendar.current calendar.timeZone = NSTimeZone(abbreviation: "UTC")! as TimeZone return calendar.startOfDay(for: Date().addingTimeInterval(-86400)).timeIntervalSince1970 }()
// // MARK: Table view datasource // override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let table = tableView as! ALTableView let cell = table.cellForRow(at: indexPath) as! CustomTableViewCell
// Get item info let array = table.array.first as! [[String:Any]] let item = array[indexPath.row] // Get item dictionary let timestamp = item["timestamp"] as! Double // Date calculations if timestamp > today { cell.dateLabel?.text = "Today" } else if timestamp > yesterday { cell.dateLabel?.text = "Yesterday" } return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tableView.numberOfRows(inSection: section) }
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let table = tableView as! ALTableView return table.heightForRow(at: indexPath) } }
#import "TableViewController.h" #import <AbstractLayer/AbstractLayer.h> #import "CustomTableViewCell.h"
@interface TableViewController () @property (nonatomic, assign) NSTimeInterval today,yesterday; @end
@implementation TableViewController
// // UITableView Datasource //
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [tableView numberOfRowsInSection:section]; }
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// Get item info NSArray *array = [(ALTableView *)tableView array].firstObject; NSDictionary *item = array[indexPath.row]; CGFloat timestamp = [item[@"timestamp"] doubleValue];
// Check dates if (timestamp > self.today) { cell.dateLabel.text = @"Today"; } else if (timestamp > self.yesterday) { cell.dateLabel.text = @"Yesterday"; } return cell; }
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return [(ALTableView *)tableView heightForRowAtIndexPath:indexPath]; }
// // Lazy Instantiation //
(NSTimeInterval)today { if (!_today) { NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; [calendar setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; _today = [calendar startOfDayForDate:[NSDate date]].timeIntervalSince1970; } return _today; }
(NSTimeInterval)yesterday { if (!_yesterday) { NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; [calendar setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; _yesterday = [[calendar startOfDayForDate:[NSDate date]] dateByAddingTimeInterval:-86400].timeIntervalSince1970; } return _yesterday; }
@end
- Run the app
Abstract Layer is as customizable as anything built from scratch.
As you've seen in the example above, the framework is fully customizable since it's built on top of native Apple UIKit
components like UITableView
& UICollectionView
.
To customize any aspect of Abstract Layer, simply:
- Subclass any of
Abstract Layer
classes to do your customizations - Conform to the
delegate
anddatasource
protocols just as you would do with a regularUITableView
&UICollectionView
Abstract Layer is not a prototyping tool, it's strictly a production-level framework. All of our customers rely on Abstract Layer in their live apps.
Abstract Layer supports lots of features on ALTableView
, so make sure to check them all out!
<tr>
<td class="row-text"><b><a href="/#/menu/table-view/xib" target="_blank">XIB</a></b><p>Reuse cells by designing them in their own XIB</p><br/></td>
<td class="row-text"><b><a href="/#/menu/table-view/authentication" target="_blank">Authentication</a></b><p>JWT is handled automatically once you provide your keys</p><br/></td>
<td class="row-text"><b><a href="/#/menu/table-view/custom-cases" target="_blank">And More...</a></b><p>Check out the dedicated section for custom cases</p><br/></td>
Error Handling Handle all kind of errors when loading your table view |
Passing Data You have FULL access to parsed data, so passing it is very simple |
Parameters Be it Header or Body, Static or Dynamic, it's all in Interface Builder |
Pagination Enabling pagination takes less than a minute |
Complex JSON Any form of JSON is supported, no matter how complex it is |
Loader Enable loaders and pull-to-refresh with 2 clicks |
Download the final project and try it out