Access portal content

Portals such as ArcGIS Online and ArcGIS Enterprise can store many types of data. Perhaps the type most commonly used by apps is a web map—a JSON description of the data in a map, along with other display and behavioral properties. Other types include tile packages, feature collections, and services. Some types, such as globe documents and map templates, may only be relevant to desktop systems. Although you can access these types of data using the API, you may not be able to use them on a mobile device. Some types of data can be taken offline.

AGSPortalItem represents an individual item stored on a portal. Each item includes the following:

  • Metadata, such as a unique identifier (ID), title, summary, description, thumbnail image, and tags
  • Binary or text-based data—for example, the JSON that defines a web map or a feature collection, or a URL pointing to a map service, or the binary data of a tile package or shapefile

Web page showing properties of a portal item including the item ID

Apps use portal items in different ways. They may show a user a range of items from a portal by combining the title, thumbnail image, and other metadata. This approach is often used to allow users to browse web maps, basemaps, or map services, and identify the item to work with. If a user selects an item, the app may then download the data stored in the portal item, for example, by opening and displaying a web map in a map, or downloading a tile package. Apps sometimes access items directly by ID if a specific item should always be used.

Your app can also add new portal items and alter existing items by adding comments and ratings, updating item information, sharing, unsharing, and deleting them, as long as the authenticated user has access permissions to do so.

You access the content of a portal item differently depending on its type. Below you can find examples of accessing different types of portal items. For more information on connecting to a portal, see Access the ArcGIS platform.

Display a web map by ID

A very common task is to display a web map from a portal. Web maps are stored as portal items and can be opened by using the ID of the item, along with the URL of the portal. If the map is not public (for example, if it is shared only with a specific group), you also need to pass in valid credentials with permission to view the map. See Access the ArcGIS platform for more information on accessing secured items.

The code below sets a map into a map view by creating a portal item from the ID of a known web map portal item. This assumes that the portal item is publicly shared, as no credentials are used.

// create a new Portal object
AGSPortal* portal = [[AGSPortal alloc]initWithURL:[NSURL URLWithString:@"https://www.arcgis.com"] loginRequired:NO];
    
// create a PortalItem based on a pre-defined portal id
AGSPortalItem* portalItem = [[AGSPortalItem alloc]initWithPortal:portal itemID:@"01f052c8995e4b9e889d73c3e210ebe3"];

// create a map from a PortalItem
AGSMap* map = [[AGSMap alloc]initWithItem:portalItem];

// set the map to be displayed in an AGSMapView
self.mapView.map = map;

There are different ways to display a map from a web map.

Open a map

You can create a map from a web map portal item without needing to display it immediately. From this, you could find out more about the contents of the map before displaying it if required—for example, getting the basemap, operational layers, bookmarks, and initial extent. To do this, load the map before setting it into a map view—see Loadable pattern for more information.

The following example gets a web map portal item, finds one of its bookmarks, and obtains its viewpoint.

// create a new Portal object
AGSPortal* portal = [[AGSPortal alloc]initWithURL:[NSURL URLWithString:@"https://www.arcgis.com"] loginRequired:NO];
    
// create a PortalItem based on a pre-defined portal id
AGSPortalItem* portalItem = [[AGSPortalItem alloc]initWithPortal:portal itemID:@"01f052c8995e4b9e889d73c3e210ebe3"];
    
// create a map from a PortalItem
self.map = [[AGSMap alloc]initWithItem:portalItem];
    
// load the map
[self.map loadWithCompletion:^(NSError * _Nullable error) {  
 if (error){
  NSLog(@"Could not load map due to error : %@",error);
 }else{
  // get a bookmark's viewpoint
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = Chula Vista"];
  NSArray *bookmarks = [weakSelf.map.bookmarks filteredArrayUsingPredicate:predicate];
  AGSBookmark *bookmark = (AGSBookmark *)bookmarks.firstObject;
  AGSViewpoint *viewPoint = bookmark.viewpoint;
  ...       
 }
}];

Note:

Remember that you must also specify credentials for a valid user with access to the item, if the item is not publicly shared.

Create a layer from a service item by ID

Portal items representing map or feature services can be used to create layers by using the portal item URL. The following example gets a portal item that represents a feature service and reads the URL. The first layer in the service is added to the map.

// create a new Portal object
AGSPortal* portal = [[AGSPortal alloc]initWithURL:[NSURL URLWithString:@"https://www.arcgis.com"] loginRequired:NO];
    
// create a PortalItem based on a pre-defined portal id
AGSPortalItem* portalItem = [[AGSPortalItem alloc]initWithPortal:portal itemID:@"9fb4d96077e24bcba72ba6cf1139c9cf"];

//Check if the portal item is a feature service     
if (portalItem.type == AGSPortalItemTypeFeatureService) {
       
 //Construct the url to the first service 
 NSURL *url = [[NSURL alloc] initWithString:[NSString stringWithFormat: @"%@%@", portalItem.serviceURL.absoluteString, @"/0"]];
 AGSServiceFeatureTable *table = [[AGSServiceFeatureTable alloc] initWithURL:url];
 AGSFeatureLayer *layer = [[AGSFeatureLayer alloc]initWithFeatureTable:table];
 [self.mapView.map.operationalLayers addObject:layer];
        
}

Find information about any portal item by ID

You can use the ID of any item stored in a portal to access it, and also to find its fields—properties such as its title, description, thumbnail image, owner, and any ratings or comments added by portal users. You can also find out the type of data it contains.

//Instantiate a portal for ArcGIS.com that connects anonymously
self.portal = [AGSPortal ArcGISOnlineWithLoginRequired:NO];

//Instantiate a portal item from ArcGIS.com using the item ID
self.portalItem = [[AGSPortalItem alloc]initWithPortal:self.portal itemID:@"1966ef409a344d089b001df85332608f"];

__weak typeof(self) weakSelf = self;
[self.portalItem loadWithCompletion:^(NSError * error) {
    //If error encountered during loading
    if(error){
        NSLog(@"Could not load portal item due to error : %@",error);
    }else{
       //Else, print some information about the item
        NSString* title = weakSelf.portalItem.title;
        NSDate* modified = weakSelf.portalItem.modified;
        NSLog(@"%@ was last modified on %@",title,modified);
    }
}];

Note:

The thumbnail of a portal item, along with the ratings and data, is not returned from the portal when you initially load the item, in order to reduce the network traffic and memory requirements. See the section below on how to access these properties.

Fetch thumbnails of items

When you create a portal item object, not all information associated with it is immediately returned. This allows you to work with the item using a minimum amount of memory and delay fetching the larger pieces of data unless, or until, you really need them. Information you need to fetch, if required, includes thumbnail images, ratings and comments, item data, group memberships, and user folder contents.

The following example shows how to get the thumbnail image of an item and print its dimensions

__weak typeof(self) weakSelf = self;

//Load the item so that it is initialized
[self.portalItem loadWithCompletion:^(NSError * error) {
    if(error){
        NSLog(@"Could not load portal  due to error : %@",error);
    }else{
        //Check if the item has a thumbnail
        if(weakSelf.portalItem.thumbnail){
            
            //Load the thumbnail so that its image is available
            [weakSelf.portalItem.thumbnail loadWithCompletion:^(NSError * error) {
                if(error){
                    NSLog(@"Could not load thumbnail due to error : %@",error);
                }else{
                    NSLog(@"%@",NSStringFromCGSize(weakSelf.portalItem.thumbnail.image.size));
                }
            }];
            
        }else{
            NSLog(@"Item has no thumbnail");
        }
    }
}];

The same applies to the thumbnails of other classes, like users, groups, and organizations. Use fetchThumbnailAsync on AGSPortalItem, AGSPortalGroup, and AGSPortalUser. Additionally, AGSPortalInfo provides fetchOrganizationThumbnailAsync and fetchPortalThumbnailAsync.

Access item data

Portal items that represent files, such as tile packages, images, documents, PDF files, and so on, can be opened, downloaded, and then stored or opened in your app or in another app. As in the previous example, you will need to specifically fetch the data of a portal item after you create it. Use the fetchDataAsync method to do this.

The following example shows how to fetch the JSON data of a portal item that represents a web map

__weak typeof(self) weakSelf = self;

//Instantiate the portal item
self.portalItem = [[AGSPortalItem alloc]initWithPortal:self.portal itemID:@"1966ef409a344d089b001df85332608f"];

//Fetch item's data
[self.portalItem fetchDataWithCompletion:^(NSData * data, NSError * error) {
    if(error){
        NSLog(@"Could not fetch data to error : %@",error);
    }else{
        if(weakSelf.portalItem.type == AGSPortalItemTypeWebMap){
            NSLog(@"Web Map JSON: %@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
        }
    }
}];

Fetch a user's content

Many apps present a list of maps or other items that belong to the current user. Users can create folders within their portal accounts to help organize their work. Apps should respect the user's view of their content and present the list of folders to the user, allowing the user to choose which folder to look at in detail.

It's easy to get all the portal items owned by the authenticated user (that represent the content and services items created by that user). AGSPortalUser represents information about a user, and from this you can retrieve all of the items and folders (represented by AGSPortalFolder) owned by the user.

//Instantiate a portal for ArcGIS.com which requires the user to log in
self.portal = [AGSPortal ArcGISOnlineWithLoginRequired:YES];

//Load the portal so that it establishes a connection and populates its user
__weak typeof(self) weakSelf = self;
[self.portal loadWithCompletion:^(NSError * error) {
    if(error){
        NSLog(@"Could not load portal  due to error : %@",error);
    }else{
        AGSPortalUser* user = weakSelf.portal.user;
        //Fetch user's content (items and folder) in the root folder
        [user fetchContentWithCompletion:^(NSArray * items, NSArray * folders, NSError * error) {
            if(error){
                NSLog(@"Could not fetch user content due to error : %@",error);
            }else{
                
                //Print items in root folder
                for (AGSPortalItem* item in items) {
                    NSLog(@"Root Folder: %@",item.title);
                }
                
                //Print items in sub-folders
                for (AGSPortalFolder* folder in folders) {
                    [user fetchContentInFolder:folder.folderID completion:^(NSArray * folderItems, NSError * error) {
                        NSLog(@"********************");
                        if(error){
                            NSLog(@"Could not find items in %@ : %@",folder.title, error);
                        }else{
                            for (AGSPortalItem* item in folderItems) {
                                NSLog(@"\t %@ : %@",folder.title,item.title);
                            }
                        }
                    }];
                }
                
            }
        }];
    }
}];

Note:

As seen in the code above, user content is another example of information that you must explicitly fetch, like portal item thumbnails and content.

To get items shared with the current user, or items owned by a different user, you need to search for portal content.

List the groups a user belongs to

Groups can be configured in different ways—some groups are open to all users; some are only accessible by invitation; and for others, any user can request to join. The groups to which the authenticated user belongs can be accessed, and for any group, the identities of the members can be found.

The AGSPortalGroup class represents a group. You can get a list of the groups a user belongs to by calling the AGSPortalUser.getGroups() method. Use fetchGroupMembershipAsync to retrieve the users in each group—after that, you can get the members from the getUsers method.

//Instantiate a portal for ArcGIS.com which requires the user to log in
self.portal = [AGSPortal ArcGISOnlineWithLoginRequired:YES];

//Load the portal so that it establishes a connection and populates its user
__weak typeof(self) weakSelf = self;
[self.portal loadWithCompletion:^(NSError * error) {
    if(error){
        NSLog(@"Could not load portal  due to error : %@",error);
    }else{
        AGSPortalUser* user = weakSelf.portal.user;

        //Load the user so that its state is properly initialized
        [user loadWithCompletion:^(NSError * error) {
            if(error){
                NSLog(@"Could not load portal user due to error: %@",error);
            }else{
                //Get the groups the user belongs to
                NSArray* groups = user.groups;

                //for each group, get its list of admins and users
                for (AGSPortalGroup* group in groups) {
                    [group fetchUsersWithCompletion:^(NSArray * users, NSArray * admins, NSError * error) {
                        NSLog(@"%@",group.title);
                        if(error){
                            NSLog(@"Could not get group users: %@",error);
                        }else{
                            for (NSString* admin in admins) {
                                NSLog(@"\tAdmin:%@",admin);
                            }
                            for (NSString* user in users) {
                                NSLog(@"\tUser:%@",user);
                            }
                        }
                    }];
                }
            }
        }];
    }
}];

From the group, you can find out if membership is by invitation only by examining the isInvitationOnly property, and if the user can share items with the group using the isViewOnly property.