如何使用Facebook SDK for .NET创建Facebook健身:课程对象

时间:2014-06-28 21:26:07

标签: facebook-graph-api facebook-c#-sdk

我正在使用MVVM Light在C#for Windows Phone 8上编写一个自行车应用程序。我已经使用Facebook SDK for .Net的最新版本(6.6.0)将我的应用程序成功链接到Facebook,并使用以下代码发布了健身:自行车常见操作:

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>)fbResult;      

        }
        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>)fbResult;

            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);
}

如您所见,我使用了List&lt;&gt;存储拆分值。不幸的是,这失败了以下例外:

  

(#100)混合显式隐式数组语法:类型为'fitness.course'的URL''的对象无效,因为'fitness_splits'类型的属性'fitness:splits'是使用与隐式数组混合的显式索引指定的句法。一次只能使用一个。

那我该如何发送健身: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 个答案:

答案 0 :(得分:0)

我想我已经解决了。我已经使用了JsonArrays和JsonObjects,并通过删除适应度来改变单个拆分和指标点的键: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);
    }
}