So after much research and fiddling around, I have found the answer. It involves creating a SOAP request to insert the Skill Users. I've posted the code below as I couldn't find any examples when I was searching for information on this topic before.
public static void AddUserSkills(Map<Id, User> userMap){
String soapbody;
//use same soapHeader as above and place in a GlobalConstants later
String soapHeader='<?xml version="1.0" encoding="utf-8"?>' +
'<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:sobject.partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="urn:partner.soap.sforce.com">'+
'<SOAP-ENV:Header>'+
'<ns2:SessionHeader>'+
'<ns2:sessionId>' + UserInfo.getSessionId() +
'</ns2:sessionId>'+
'</ns2:SessionHeader>'+
'</SOAP-ENV:Header>'+
'<SOAP-ENV:Body>'+
'<ns2:create>';
String soapFooter ='</ns2:create>' +
'</SOAP-ENV:Body>'+
'</SOAP-ENV:Envelope>';
Set<String> skillsToGet = new Set<String>();
Map<String, Skill> skillNameToSkill = new Map<String, Skill>();
Map<String, String> skillUserMap = new Map<String, String>();
//Put this in a method later that can be reused between RemoveUserSkills and AddUserSkills
for(user u: userMap.values()){
if(u.Skills__c != null){
String[] tmpGroups = u.Skills__c.split(';');
if(u.IsActive){
for(String q : tmpGroups){
if(!skillsToGet.contains(q)){
skillsToGet.add(q);
}
}
}
}
}
List<Skill> skills = [SELECT Id,DeveloperName
FROM Skill WHERE
DeveloperName in: skillsToGet];
for(Skill s : skills){
if(!skillNameToSkill.containsKey(s.DeveloperName)){
skillNameToSkill.put(s.DeveloperName, s);
}
}
for(user u : userMap.values()){
if(u.Skills__c != null){
List<String> tmpSkills = u.Skills__c.split(';');
Set<String> skillsSet = new Set<String>();
if(u.IsActive){
skillsSet.addAll(tmpSkills);
for(String s : tmpSkills){
soapbody +='<ns2:sObjects>'+
'<ns1:type>SkillUser</ns1:type>'+
'<ns1:Id xsi:nil="true"/>'+
'<SkillId>' + skillNameToSkill.get(s).Id+'</SkillId>'+
'<UserId>' + + u.Id +'</UserId>'+
'</ns2:sObjects>';
}
}
}
}
System.debug('Soap Body: ' + soapbody);
//tune batch set size accordingly later for optimization within @future call time out limit. Depends if 200 records can be created within 120 seconds
ApexWebServiceProxy.HttpRequest(GlobalConstants.partnerSoapEndPoint, 'POST', '"', 'text/xml', soapHeader + soapbody + soapFooter);}
Hope this helps other individuals trying to accomplish the same task via Apex.
And for completeness, here's the ApexWebServiceProxy class.
public with sharing class ApexWebServiceProxy {
@Future(callout=true)
public static void HttpRequest(String uri, String httpMethod, String soapAction, String contentType, String body ) {
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(uri);
req.setMethod(httpMethod);
req.setHeader('SOAPAction',soapAction);
req.setHeader('Content-Type', contentType);
req.setBody(body);
HttpResponse res = h.send(req);
}}
And finally the Global Constants class
public class GlobalConstants {
public static final String partnerSoapEndPoint = System.URL.getSalesforceBaseUrl().toExternalForm()+'/services/Soap/u/33.0';
}