There is an API class with a method specifically for this. In version 1.9.1.0 you can find the function defined in app/code/core/Mage/Catalog/Model/Category/Api.php
line 467
public function assignProduct($categoryId, $productId, $position = null, $identifierType = null)
So, my recommendation is to scrap using $product->setCategoryIds() and utilize this method instead. $product->setCategoryIds() works just fine if you know ALL the categories the product should belong too, and don't care about position. However it can easily cause problems for you especially if you're doing scripting work on existing products, as it will blow out any other categories the product may have been assigned to (that you didn't supply the id for) as well as blow out the current position the product has been assigned even if the product was already associated to the category prior to performing your scripting work.
Anyways... so if we examine the method's definition, we can see that we need to already have a product id. So if we were to reference your original code, you'll want to save the product, then associate it to the category/categories.
$i = 0;
foreach ($array as $product) {
createProduct($params, $i);
$i++;
if($i == $count){
// finish and continue
}
}
function createProduct($params, $position)
{
$product = Mage::getModel('catalog/product');
$product->setCreatedAt(strtotime('now'));
$product->setAttributeSetId(11);
$product->setName(xxxxxx);
$product->setPrice(xxxxx);
$product->setDescription(xxxxxxx);
// and so on...
$category_ids = array('xx','xxx');
try {
$product->save();
$api = Mage::getSingleton('catalog/category_api');
foreach ($category_ids as $category_id) {
$api->assignProduct($category_id, $product->getId(), $position);
}
}
catch (Exception $ex) {
// catch error
}
}
Mage_Catalog_Model_Resource_Category::_saveCategoryProducts
.