The YesGraph SDK is written in a modular architecture, making it fully extensible. A few examples of using SDK components are provided below:

Using YesGraph SDK Suggestions & Contact List with Custom UI

If the built-in YesGraph Share Sheet and Contact List do not fit your needs, you can still use the YesGraph API to generate suggestions manually. The following guide will explain how to use contact sources and to connect to the YesGraph API. Here’s how to get started:

  • Set up a unique user_id for the user
  • Set the client key corresponding to the user_id, using your own server
  • Fetch contacts from the SDK

User ID

  • First, we set the user_id and user information using the following code:
YesGraph.shared().configureWithUserId("<USER_ID>")

let source = YSGSource()
source.name = "Name"
source.email = "Email"
source.phone = "+1 123 123 123"

YesGraph.shared().contactOwnerMetadata = source
[[YesGraph shared] configureWithUserId:@"<USER_ID>"];

YSGSource* source = [[YSGSource alloc] init];
source.name = @"Name";
source.email = @"Email";
source.phone = @"+1 123 123 123";
        
[[YesGraph shared] setContactOwnerMetadata:source];

Client Key

  • Next, we set the client_key associated with the user_id. Make sure to fetch the client key using the YesGraph API.
YesGraph.shared().configureWithClientKey(jsonResult["message"] as! String)
[[YesGraph shared] configureWithClientKey:clientKey];

Here is a full example of the call to your server to retrieve the client key, and then setting the client key in the SDK.

let urlPath: String = "<YOUR SERVER URL>" + YesGraph.shared().userId!
// e.g. "https://yesgraph-client-key-test.herokuapp.com/client-key/"

let url: NSURL = NSURL(string: urlPath)!
let request: NSURLRequest = NSURLRequest(URL: url)
let session: NSURLSession = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
    
    let jsonResult: NSDictionary = try! (NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary)!
    print("AsSynchronous\(jsonResult)")
    
    YesGraph.shared().configureWithClientKey(jsonResult["message"] as! String)
    
});
task.resume()
NSString *urlPath = [NSString stringWithFormat:@"<YOUR SERVER URL>/%@", [YesGraph shared].userId];
// e.g. "https://yesgraph-client-key-test.herokuapp.com/client-key/"

NSURL *url = [NSURL URLWithString: urlPath];
NSURLSession *session = [NSURLSession sharedSession];

[[session dataTaskWithURL:url
        completionHandler:^(NSData *data,
                            NSURLResponse *response,
                            NSError *error) {
            NSError *jsonError;
            NSDictionary *jsonResult = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
            
            NSString *clientKey = [jsonResult objectForKey:@"message"];
            
            [[YesGraph shared] configureWithClientKey:clientKey];
            
        }] resume];

Fetch Contact List

  • Fetch user’s contactList with configured by calling fetchContactListWithCompletion:. This method first checks if the contactList is available in the cache, otherwise it checks the user’s local phone address contacts, uploads them to YesGraph, and gets the ranked results in the form of a YSGContactList object.
YesGraph.shared().fetchContactListWithCompletion{(contactList, error) -> Void in
    // Handle success or failure
    // Do something with the returned contactList
}
[self.onlineSource fetchContactListWithCompletion:^(YSGContactList *contactList, NSError *error){
    if (!error) {
    }
    if (completion) {
        // Do something with the returned contactList
    }
}];

If the call is successful, YSGContactList object is returned, which has all the contacts stored in entries attribute.

Filter by Email or Phone

To get only the contacts that have emails, or only the contacts that have phone numbers (for example for an SMS only service), use the following convenience methods on YSGContactList:

// Get only the email entries
let emailContactList: YSGContactList = contactList.emailEntries()
// Get only the email entries
YSGContactList *emailContactList = [contactList emailEntries];
// Get only phone entries
let phoneContactList: YSGContactList = contactList.phoneEntries()
// Get only phone entries
YSGContactList *phoneContactList = [contactList phoneEntries];

Get Suggestions

Next we want to split the list into the top N suggested entries, and sort the rest of the contacts alphabetically. The second method sends the suggested entries up to YesGraph’s API.

// Get the top N suggested entries
let suggestedContacts = contactList?.suggestedEntriesWithNumberOfSuggestions(YSGDefaultInviteNumberOfSuggestions)

// Get the rest of the entries sorted
let sortedContacts = contactList?.sortedEntriesWithNumberOfSuggestions(YSGDefaultInviteNumberOfSuggestions)
// Get the top N suggested entries
NSArray<YSGContact *> *suggestedContacts = [contactList suggestedEntriesWithNumberOfSuggestions:YSGDefaultInviteNumberOfSuggestions];

// Get the rest of the entries sorted
NSDictionary <NSString *, NSArray <YSGContact *> *> *sortedContacts = [contactList sortedEntriesWithNumberOfSuggestions:self.YSGDefaultInviteNumberOfSuggestions]

The class provides an utility method called suggestedEntriesWithNumberOfSuggestions to automatically process entries and returns an array of suggested entries.

Using YesGraph SDK Share Services

YesGraph iOS SDK provides multiple share services out of the box. It is possible to use each of those without using the YesGraph SDK Share Sheet UI.

The services that are currently provided:

  • YesGraph Invite Service, which uses phone’s contact book to share via Messages or Email,
  • Facebook,
  • Twitter.

All services inherit from the YSGShareService class, which is really easy to use.

To use a specific share service, all you have to do is to instantiate it and call triggerServiceWithViewController: method.

let facebookService = YSGFacebookService()
facebookService.triggerServiceWithViewController(self)
YSGFacebookService *facebookService = [YSGFacebookService new];
[facebookService triggerServiceWithViewController:self];

The share service will use the provided view controller to present a modal screen.

With YesGraph Invite Share Service, there is a bit more configuration required, since it uses a specific YesGraph API. It requires you to create the same contact source chain as is described under step 1. in the section above.

Once you have an instance of YSGOnlineContactSource, you can use it with YSGInviteService.

let inviteService = YSGInviteService(contactSource: onlineContactSource, userId: userId)
inviteService.triggerServiceWithViewController(self)
YSGInviteService *inviteService = [[YSGInviteService alloc] initWithContactSource:onlineContactSource userId:userId];
[inviteService triggerServiceWithViewController:self];

Triggering the invite service will display the YesGraph Contact Book UI, where the user can select contacts to invite / share). You can also add yourself as the delegate (YSGShareServiceDelegate) of the invite service, so you will receive notifications when some user action is made.

inviteService.delegate = self
inviteService.delegate = self;

If you would like to only include contacts that have phone numbers, or contacts that have email addresses, you can set the invite service

// Only include contacts that have one or more Email Addresses
inviteService.inviteServiceType = YSGInviteServiceType.Email

// Only include contacts with one or more phone numbers
inviteService.inviteServiceType = YSGInviteServiceType.Phone
// Only include contacts that have one or more Email Addresses
inviteService.inviteServiceType = YSGInviteServiceTypeEmail;

// Only include contacts with one or more phone numbers
inviteService.inviteServiceType = YSGInviteServiceTypePhone;

Using YesGraph SDK to call YesGraph API endpoints

YesGraph SDK uses a separate component to communicate with YesGraph API. The logic is implemented in the YSGClient class. To use it, you need a client key (how to generate one is described in detail in Authentication).

let client = YSGClient()
client.clientKey = clientKey
YSGClient *client = [[YSGClient alloc] init];
client.clientKey = clientKey;

Once you have a fully configured YSGClient object, you can easily call YesGraph API, using the native methods such as fetchAddressBookForUserId:completion:.

client.fetchAddressBookForUserId(userId) { response, error in 
    // Handle response
}
[client fetchAddressBookForUserId:userId completion:^(id responseObject, NSError *error) { 
    // Handle response
}];

Completion block is always called asynchronously when network request is completed and provides an error object and serialized response object (if applicable). It is modelled after AFNetworking, so you can also call alternative endpoints with GET or POST methods available on YSGClient.

client.GET("address-book/" + userId, parameters: nil) { response, error in }
[client GET:[NSString stringWithFormat:@"address-book/%@", userId] parameters:nil completion:^(YSGNetworkResponse * _Nullable response, NSError * _Nullable error) { }];

Read more about available methods in the Architecture section.

Creating a Custom Share Service

While YesGraph SDK provides a few sharing services out of the box, it still might be needed to create your own specific sharing service. To do this, you need to subclass YSGShareService class, which is an abstract implementation of a share service.

YSGShareService has a few properties that you need to set, by overriding the getters, since properties are read-only.

The example below displays how to override getter for service name.

public class MyShareService : YSGShareService {
    override public var name: String {
        get {
            return "My share service"
        }
    }
}
@implementation MYShareService

- (NSString *)name
{
    return @"Service Name";
}

@end

Be sure to provide at least name and serviceImage values, while other properties provide fine-grain customization, of how your service is displayed in the share sheet.

The main method to implement is triggerServiceWithViewController:, which you need to override in your subclass. This method is called when the user selects your service in the share sheet. As a parameter, the parent view controller is provided, so you can use it to display a modal view controller if required.

override func triggerServiceWithViewController:(viewController : UIViewController) {
    // Your share service code
}
- (void)triggerServiceWithViewController:(UIViewController *)viewController
{
    // Your share service code
}

Once you have implemented the method, you can use the sharing service in YesGraph Share Sheet, as described in the section below.

Adding Sharing Services to YesGraph Share Sheet

YesGraph Share Sheet is fully extensible and is implemented in YSGShareSheetController class. Once you have concrete instances of YSGShareService classes, you can use them with share sheet.

let shareController = YSGShareSheetController(services:[ service ], delegate: delegate, theme:nil)
YSGShareSheetController *shareController = [[YSGShareSheetController alloc] initWithServices:@[ service ] delegate:delegate theme:nil];

Once you have YSGShareSheetController instance, you can represent it any way you like, as described in Getting Started.

Disabling Native Messaging Sheets in Invite Service

Invite Share Service in YesGraph SDK is implemented in the YSGInviteService class and it displays a contact list to the user. The user can select multiple email and/or phone contacts to share a message to. By default the Invite Share Service will display native messaging sheets defined in Disabling native messaging sheets in MessageUI iOS framework. If you are using a custom messaging or emailing framework, you might want to disable the native messaging sheets. You can do this using Invite Share Service nativeMessageSheet and nativeEmailSheet properties. Both are set to true by default.

inviteService.nativeMessageSheet = false
inviteService.nativeEmailSheet = false
inviteService.nativeMessageSheet = NO;
inviteService.nativeEmailSheet = NO;

Retrieving a Specific Service from the Share Sheet

If you used the Convenience API to initialize your share sheet, you might be having trouble finding the specific share service to customize it’s properties. YSGShareSheetController stores all services in the services property, which is an array of YSGShareService objects. To retrieve the service you are looking for, loop through the array and pull out the service you need by either checking it’s class or name.

The example below finds Invite Share Service (YSGInviteService class) in an instance of share sheet.

let shareController  = YesGraph.shared().shareSheetControllerForAllServicesWithDelegate(self)

for shareService in shareController.services
{
    if let inviteService = shareService as? YSGInviteService
    {
        // Do something with invite service
        break
    }
}
YSGShareSheetController *shareController  = [[YesGraph shared] shareSheetControllerForAllServicesWithDelegate:self];

for (YSGShareService* shareService in shareController.services)
{
    if ([shareService isKindOfClass:[YSGInviteService class]])
    {
        YSGInviteService *inviteService = (YSGInviteService *)shareService;
        // Do something with invite service
        break;
    }
}

Invites Sent

By telling YesGraph which contacts have been invited, we can tune our rankings to your users, to achieve better results. If you are using your own UI with YesGraph SDK components, we highly recommend you use this functionality.

You can hit this API endpoint using the convenience method updateInviteService:.

// Get an array of YSGContacts that have been invited
var invitees = [YSGContact]()

// ADD INVITED YSGContacts HERE

// POST invites to YesGraph API via convenience method
client.updateInvitesSent(invites, userId) { error in
// Handle Error Here
}
// Get an array of YSGContacts that have been invited
NSArray<YSGContact *> *invitees = [YSGTestMockData mockContactList].entries;

// ADD INVITED YSGContacts HERE

// POST invites to YesGraph API via convenience method
[self.client updateInvitesSent:invitees forUserId:<USERID> completion:^(NSError *_Nullable error) {
        // Handle Error Here
    }
];]