Как создать Facebook fitness: объект курса с использованием Facebook SDK для .NET

#facebook-graph-api #facebook-c#-sdk

#facebook-graph-api #facebook-c #-sdk

Вопрос:

Я пишу приложение для велоспорта на C # для Windows Phone 8, используя MVVM Light. Я успешно связал свое приложение с Facebook, используя последнюю версию (6.6.0) Facebook SDK для .Net, и опубликовал общее действие fitness: bikes, используя следующий код:

 private async void ExecuteShareButtonClicked()
{
    // Retrieve the Facebook session from Isolated Storage...
    var session = SessionStorage.Load();
    if (session == null)
        return;

    // Fire up the ProgressIndicator...
    ProgressIndicatorText = Resources.AppResources.FacebookUpdatingStatus;
    IsProgressIndicatorVisible = true;


    // Upload the course object to Facebook...
    string courseId = await CreateCourse(session);

    // Create the parameters for the fitness.bikes action
    if (courseId != string.Empty)
    {
        var bikesParams = new Dictionary<string, object>();

        bikesParams.Add("course", courseId);
        bikesParams.Add("fb:explicitly_shared", true);
        bikesParams.Add("start_time", RideModel.RideStartTime.ToString("o"));
        bikesParams.Add("end_time", RideModel.RideFinishTime.ToString("o"));
        if (MessageText != string.Empty)
            bikesParams.Add("message", MessageText);               

        var fbClient = new FacebookClient(session.AccessToken);

        // Upload to FB
        try
        {
            string postId = string.Empty;

            dynamic fbResult = await fbClient.PostTaskAsync("/me/fitness.bikes", bikesParams);
            var result = (IDictionary<string, object>)fbResu<      

        }
        catch (Exception ex)
        {
            messageBoxService.Show(Resources.AppResources.FacebookErrorPostingStatus   ex.Message, Resources.AppResources.FacebookError);
        }
    }

    // Clear the ProgressIndicator
    ProgressIndicatorText = string.Empty;
    IsProgressIndicatorVisible = false;

    // Go back to the ride summary page...
    navigationService.GoBack();
}


private async Task<string> CreateCourse(FacebookSession session)
{
    string returnId = string.Empty;

    if (session != null)
    {
        var fbClient = new FacebookClient(session.AccessToken);

        // Convert the ride length from metres (as stored by the app) to kilometres or miles, depending upon the
        // value of MapUnits. MapUnits is an enum property which tells the programmer what units 
        // the user wants displaying. 

        var distValue = UnitConversion.ConvertDistance(RideModel.RideLength, MapUnits);
        string unitText = "m";

        switch (MapUnits) // MapUnits is an enum which tells the program if the user
        {
            case Measurement.Metric:
                unitText = "km";
                break;
            case Measurement.Imperial:
                unitText = "mi";
                break;
            default:
                break;
        }

        var courseParams = new Dictionary<string, object>();

        courseParams.Add("fb:appId", App.FacebookAppId);
        courseParams.Add("og:title", RideModel.RideName);
        courseParams.Add("og:image", "http://marknotgeorge.co.uk/ApplicationIcon.png");
        courseParams.Add("fitness:distance:value", distValue);
        courseParams.Add("fitness:distance:units", unitText);
        courseParams.Add("fitness:duration:value", RideModel.RideTime.TotalSeconds);
        courseParams.Add("fitness:duration:units", "s");

        var objectParams = new Dictionary<string, object>();
        objectParams.Add("object", courseParams);

        try
        {
            dynamic fbResult = await fbClient.PostTaskAsync("/me/objects/fitness.course", objectParams);
            var result = (IDictionary<string, object>)fbResu<

            returnId = (string)result["id"];
        }
        catch (Exception ex)
        {
            messageBoxService.Show(Resources.AppResources.FacebookErrorPostingStatus   ex.Message, Resources.AppResources.FacebookError);
        }

    }

    return returnId;
}
 

Теперь я хочу добавить дополнительные элементы, такие как время разделения и карта маршрута с использованием ActivityDataPoints. Вот код, который я добавляю в CreateCourse для добавления разделений:

 if (ShareSplits) // If the user has specified to upload split times, this is true.
{
    courseParams.Add("fitness:splits:unit", unitText);
    var splitParams = new List<Dictionary<string, object>>();
    foreach (var item in RideModel.IntervalPoints)
    {
        // Interval times are stored every unit (kilometre or mile depending on user settings), 
        // plus a final one at the end of the ride. If the ride length is less than a unit, 
        // we only have one split to send, giving an inaccurate result. 
        if (item.Interval >= 1)
        {
            var param = new Dictionary<string, object>();
            param.Add("fitness:splits:values:value", item.IntervalTime.TotalSeconds);
            param.Add("fitness:splits:values:units", "s");
            splitParams.Add(param);
        }
    }
    courseParams.Add("fitness:splits", splitParams);
}
 

Как вы можете видеть, я использовал список<> для хранения разделенных значений. К сожалению, это не удается со следующим исключением:

(# 100) Смешанный явно неявный синтаксис массива: объект по URL » типа ‘fitness.course’ недопустим, поскольку свойство ‘fitness: splits’ типа ‘fitness_splits’ было указано с обоими явными индексами, смешанными с неявным синтаксисом массива. Одновременно можно использовать только один объект.

Итак, как мне отправить фитнес: разбиения и ActivityDataPoints? Должен ли я использовать массив вместо списка?

РЕДАКТИРОВАТЬ: я изменил блок кода if (ShareSplits) на следующий, что приводит к тому же исключению:

 if (ShareSplits)
{
    Dictionary<string, object>[] splitParams;

    courseParams.Add("fitness:splits:unit", unitText);

    if (RideModel.IntervalPoints.Count > 1)
    {
        splitParams = new Dictionary<string, object>[(RideModel.IntervalPoints.Count - 1)];
        for (int i = 0; i < (RideModel.IntervalPoints.Count - 1); i  )
        {
            var param = new Dictionary<string, object>();
            param.Add("fitness:splits:values:value", RideModel.IntervalPoints[i].IntervalTime.TotalSeconds);
            param.Add("fitness:splits:values:units", "s");
            splitParams[i] = param;
        }
        courseParams.Add("fitness:splits", splitParams);
    }
}
 

Ответ №1:

Я думаю, что я решил это. Я использовал JSONArrays и JSONObjects и изменил ключи для отдельных точек разделения и показателей, удалив префикс fitness: splits и fitness:metrics .

Сегмент разделения теперь выглядит следующим образом:

 if (ShareSplits)
{
    courseParams.Add("fitness:splits:unit", unitText);

    if (RideModel.IntervalPoints.Count > 1)
    {
        JsonArray splitParams = new JsonArray();
        for (int i = 0; i < (RideModel.IntervalPoints.Count - 1); i  )
        {
            JsonObject splitPointParams = new JsonObject();
            splitPointParams.Add("values:value", RideModel.IntervalPoints[i].IntervalTime.TotalSeconds);
            splitPointParams.Add("values:units", "s");
            splitParams.Add(splitPointParams);                            
        }
        courseParams.Add("fitness:splits", splitParams);
    }
}