Developing Windows Applications in C++ (Articles Series)

Posted in C++ on July 31st, 2011 by Admin

Kate GregoryWe got just published “Developing Windows Applications in C++”,  an article series created by C++ Most Valuable Professional Kate Gregory. This material is aimed at C++ developers who want to learn how to write Windows applications. It won’t teach you C++, or how to use Windows as an end user. But if you know C++ and Windows already, and want to write applications, this is the right spot. It’s divided into 6 chapters.

 

  1. The tools you need
    In this chapter you will learn about the Windows SDK and how to get it. Visual Studio will be introduced and the different versions explained. All the demos and samples in this material were developed using Visual Studio 2010 Express, which is available at no charge.
  2. Windows basics
    Here you will see how Windows works under the hood. You’ll meet words like “message” and “handle” that are everywhere for Windows programmers. Windows terminology can be different from what you’re used to, so this chapter clarifies a lot of it. You’ll also see the various ways that Windows interacts with your application and provides functionality for you.
  3. A simple Windows application
    In this chapter, you’ll meet the simplest-possible Windows application and understand its structure, and how it works. These concepts will recur in every Windows application you write. You’ll also see the starter application that is generated by Visual Studio, and how it differs from the simplest-possible application.
  4. Typical Windows tasks
    This chapter starts by transforming the starter application from chapter 3 from a C-style collection of functions into a more object-oriented C++ application. Then it uses Direct2D to paint a simple UI. The sample is further refined by adding reactions to mouse and keyboard events, and then a control is added. You can also see how to show a message box to your users. This gives you all the building blocks for a user interface.
  5. Working with COM
    A lot of Windows functionality is provided through COM, the Component Object Model. This chapter focuses on consuming functionality offered by Windows through COM. It covers COM concepts, demonstrates calling the Text-to-Speech capabilities of Windows through COM, and explains many of the coding patterns and conventions you will see in almost every application that uses COM.
  6. Taking the next steps
    This chapter calls out nine other Windows-related technologies that might interest you, and provides links to starting points you can use to explore those. With the foundation provided by the first six chapters, you can start to incorporate many other technologies into your own Windows applications.


Visual C++ Team Blog

Tags: , , , ,

ASP.NET MVC: Unauthenticated User Always Redirected to ~/Account/LogOn Despite Custom Sign In Url

Posted in Programming Tips on July 30th, 2011 by Admin

By default new ASP.NET MVC projects redirect any unauthenticated users who request resources that require authentication to the /Account/LogOn action. The log on page is defined in the web.config authentication section.

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>

It is my preference for users to “Sign in” instead of “Log on” so I changed the web.config to the following and changed the action method name from LogOn to SignIn.

<authentication mode="Forms">
  <forms loginUrl="~/Account/SignIn" timeout="2880" />
</authentication>

After the change I tried accessing a page that required the user to be authorized with and unauthorized user and to my surprise, the site redirected me to /Account/LogOn and I got a 404 error saying the the resource could not be found. It turns out this is a known issue with the ASP.NET MVC when the WebMatrix.Data.dll and WebMatrix.DataWeb.dll are added to the deployable assemblies collection. This issue can be fixed by adding the following key to the appSettings section of the web.config.

<appSettings>
  ...
  <add key="loginUrl" value="~/Account/SignIn" />
</appSettings>

I presume this will be fixed in the next release of ASP.NET MVC as a bug has been logged on Microsoft Connect here.


Nick Olsen’s Programming Tips

Tags: , , , , , , , ,

GoingNative: a New Channel 9 Show Dedicated to Native Development

Posted in C++ on July 30th, 2011 by Admin

imageGoingNative is a new, monthly show on Channel 9 dedicated to native development and native developers, with an emphasis on modern C++. In our inaugural episode, we keep things light and easy as we introduce you to what we’re doing, why we’re doing it, and how it will go down.

The main goal of episode 0 is to introduce the cast of characters, including your hosts Charles Torre and Diego Dagum, and to present some ideas of how we think this show will be organized and executed. For example, Diego and Charles will typically construct the show, iterate through some code demos of varying complexity, converse with native developers from Microsoft and across the industry, and then destruct the show. 
In this first episode we do talk about and demo a few new C++ features (shared_ptr, lambdas, auto) and have a conversation with Ale Contenti – development manager of VC’s front-end compiler, libraries, and IDE.

[You can play around with the demos in this episode by downloading the free VC++ Express IDE]

Table of Contents (click time code links to navigate player accordingly)

[00:09] Charles and Diego construct the show and talk about modern C++ (how ’bout that set, eh?)
[07:27] Diego demos shared_ptr
[10:01] Charles and Diego chat briefly about C++ lambdas
[10:32] Diego demos lambdas
[12:13] Charles and Diego chat briefly about C++ auto keyword (seen in the lambdas demo)
[13:30] Charles and Diego talk about the audience and how you can help us fly this plane
[15:32] Charles interviews Ale Contenti
[26:35] Charles and Diego destruct the show ( it won’t usually take this long Smiley )

 

Go native!


Visual C++ Team Blog

Tags: , , , , ,

Compile-time regex matcher using constexpr

Posted in C++ on July 28th, 2011 by Admin

With my growing constexpr fascination, I thought of using it for something that would be really hard using template meta-programs. How about implementing a compile-time regular expression matcher? Fortunately, a simple regular expression matcher has already been written by Rob Pike. I just rewrote it using constexpr: single return statement in functions, no modifications to the parameters, abundant ternery operators, and recursion. Here we go…

To compile it, as of today, you need g++ 4.6 or better. You’ve to pass REGEX and TEXT as #defines while compilation. For instance, -D REGEX=o$ -D TEXT=Foo It matches!

I used two macros TO_STR and To_STR_IMPL to convert the REGEX and TEXT into string literals. #R is basically using the preprocessor stringification technique. For some reason I need two separate TO_STR macros for TEXT substitution and stringification. Seems like the gcc preprocessor can’t do those two things in a single macro.

Have fun!


C++ Truths

Tags: , , , ,

Apple adds iTunes Store access for 33 more countries

Posted in IPhone App Programming on July 26th, 2011 by Admin


On the evening of July 22nd Apple notified developers it would be adding iTunes Store access to 33 additional countries. The countries include:

Algeria, Angola, Anguilla, Antigua and Barbuda, Azerbaijan, Bahamas, Bahrain, Barbados, Belarus, Belize, Bermuda, Bolivia, British Virgin Islands, Brunei, Cayman Islands, Cyprus, Dominica, Ghana, Grenada, Guyana, Iceland, Montserrat, Nigeria, Oman, St. Kitts and Nevis, St. Lucia, St. Vincent and The Grenadines, Suriname, Tanzania, Trinidad and Tobago, Turks and Caicos, Uzbekistan, Yemen

Which brings us to a total of 123 countries.


Mobile Orchard

Tags: , , , , , ,

Tris sourcecode on Google Code

Posted in IPhone App Programming on July 25th, 2011 by Admin

This game got banned on Appstore but still it is a very valuable resource to understand how to develop a game for iPhone. You can download the source code of Tris on google code.

iPhoneDevelopmentBits

Tags: , , ,

Want speed? Use constexpr meta-programming!

Posted in C++ on July 23rd, 2011 by Admin

It’s official: C++11 has two meta-programming languages embedded in it! One is based on templates and other one using constexpr. Templates have been extensively used for meta-programming in C++03. C++11 now gives you one more option of writing compile-time meta-programs using constexpr. The capabilities differ, however.

The meta-programming language that uses templates was discovered accidently and since then countless techniques have been developed. It is a pure functional language which allows you to manipulate compile-time integral literals and types but not floating point literals. Most people find the syntax of template meta-programming quite abominable because meta-functions must be implemented as structures and nested typedefs. Compile-time performance is also a pain point for this language feature.

The generalized constant expressions (constexpr for short) feature allows C++11 compiler to peek into the implementation of a function (even classes) and perform optimizations if the function uses constants (literals) only. Constants can be integral, floating point, as well as string literals. The signature of constexpr functions is just like regular C++ functions but the body has several restrictions, such as only one return statement is allowed. Nevertheless, the syntax of constexpr functions is significantly friendlier than that of template-based meta-functions. Contrary to the design of templates, designers of generalized constant expressions are well-aware of its meta-programming capabilities.

In my view, the most interesting aspect of constexpr is its speed. constexpr functions can perform compile-time computations at lightening speed. To compare the performance I implemented an is_prime algorithm in 3 different ways. Here is the algorithm in regular C++:

Here is the a template version of the same algorithm. Obviously, it is implemented as a collection of meta-functions in terms of structures.

The above meta-program is a recursive implementation because that’s how pure functional languages work. The is_prime_impl meta-function does all the heavy lifting. To prevent infinite regression, lazy instantiation technique is used. All I can say at this point is you’ve to stare at the code to make sense out of it.

And that’s precisely the point: C++03 meta-programs are often unreadable and hard to comprehend. Not anymore! Here is the constexpr version of the same algorithm.

Well, I agree, although this version uses friendlier syntax, is not quite easy to read. Just like the previous one, it is recursive. I would say just get used to it! You can’t live without recursion in C++ meta-programming world. Secondly, every function has a single return statement and the codifying logic for detecting primality requires abundant use of the ternary operator.

As long as parameter number is an integral constant, this constexpr version will compute the result at compile-time (C++11 compilers only). And when the number is a run-time integer, this same function is perfectly capable of computing the result at run-time. So you don’t need two different versions of the same program: one for compile-time and another for run-time. One implementation does it all!

Now that we have the implementations, lets talk performance. Take 4256233. This is 30,000th prime number! How long does the template version take to check if it is prime? It cannot! Yes, g++ 4.7 fails to compile is_prime<4256233>::value because the computation exceeds the default (900) limit of the recursive template instantiations. So I used -ftemplate-depth-2100 allowing 2100 recursive instantiations! Does it work? Yes! How long does it take? About 1 second! That’s not bad at all, you say. How fast is constexpr? About 0.154 seconds!

Seems like templates are not too far behind. Wrong! How about fifth million prime number! It is 86028121. I could not get it to work with g++ 4.7. Somewhere in the range of 9300 recursive instantiations g++ seg-faults. That’s brutal! isn’t it? 9000+ recursive instantiations? There has to be a better way.

So how long does the constexpr take for our fifth million prime number? 0.220 seconds! That’s right! This large prime number makes almost no impact on constexpr compilation time. What could be the reason? There are no template instantiations. C++ compilers always did compile-time computations whenever it was possible. constexpr now allows user-defined abstractions to hide those computations behind functions and yet allow compilers to see through them.
By the way, I had to increase to depth of default allowed constexpr recursion using -fconstexpr-depth=9300. The compiler bails out after this limit and resorts to run-time computation. Remember, the function is perfectly good for run-time computation as well (unlike templates version).

I hope this little exercise will convince you that constexpr is the way to go for static meta-programming in C++ as long as you are dealing with literals (integral, floating point numbers, and strings). It is not clear whether constexpr functions are suitable for manipulating complex meta-programmable types, such as mpl::vector and related meta-functions, such as mpl::contains, mpl::push_back, and so on. If you are interested in playing with the above example more, here is the code: is_prime.cpp and prime-test.sh


C++ Truths

Tags: , , ,

Visual Basic Windows Phone 7 Series #2. How to create a microphone application for Windows Phone 7

Posted in Visual Basic on July 23rd, 2011 by Admin

In our last post, I explained how to create a mini browser for Windows Phone 7. In this blog, I want to share a sample that will help you to create a microphone application for Windows Phone 7. This application will have the feature to capture audio from a microphone and then play back the captured audio. I will now demonstrate how easy it is to create a microphone application for Windows Phone 7, using Visual Basic for Windows Phone Developer Tools.

The microphone application can be created in 4 simple steps as follows:

  1. Create a sample application and add controls
  2. Add event handlers
  3. Build and debug the application
  4. Rebuild in the release mode before publishing

Prerequisites:

To create the microphone application, let’s follow the 4 simple steps mentioned earlier:

Step 1 - Create a sample application and add controls

Create a sample application

  1. Create a new project and browse to the “Silverlight for Windows Phone” node.
  2. Select the “Windows Phone Application” template.
  3. Enter a name for the application. 
  4. Click OK. The MainPage.xaml page is displayed. 
  5. In Solution Explorer, right-click the application name and then select Add Reference. 
  6. Select Microsoft.Xna.Framework from the list, and then click Ok. 

 

Add controls

  1. Click the MY APPLICATION text. In the Properties window, change the text property to “SILVERLIGHT MICROPHONE SAMPLE”.
  2. Click the page name text. In the Properties window, change the text property to “press record”.
  3. In Solution Explorer, right-click the application name and add a new folder.
  4. Rename the new folder as “Images”, and add the required icon images to the folder.
  5. From the toolbox, drag and drop the Image control to the design surface.
  6. Click the Image control. In the Properties window, change the text property to “StatusImage”.
  7. Change the source property of the Image control to link it to the icon image you added in the Images folder.
  8. Add the following XAML code to create the record, play, and stop buttons. This code also links the buttons to the respective icon images from the Images folder.

    <phone:PhoneApplicationPage.ApplicationBar>

          <shell:ApplicationBar IsVisible="True" IsMenuEnabled="False">

             <shell:ApplicationBar.Buttons>

                <shell:ApplicationBarIconButton x:Name="recordButton" Text="record" IconUri="/Images/record.png" Click="recordButton_Click" IsEnabled="True"/>

                <shell:ApplicationBarIconButton x:Name="playButton" Text="play" IconUri="/Images/play.png" Click="playButton_Click" IsEnabled="False"/>

                <shell:ApplicationBarIconButton x:Name="stopButton" Text="stop" IconUri="/Images/stop.png" Click="stopButton_Click" IsEnabled="False"/>

             </shell:ApplicationBar.Buttons>

          </shell:ApplicationBar>

    </phone:PhoneApplicationPage.ApplicationBar>

Your application now looks like this:

 

Step 2 – Add event handlers

Adding event handlers is one of the important tasks. These event handlers are required to start capturing an audio, stop capturing the audio, and then play back the captured audio.

To add the event handlers:

  1. Open the MainPage.xaml.vb page, and add the following code:

    Imports System.IO

    Imports System.Threading

    Imports System.Windows

    Imports System.Windows.Media.Imaging

    Imports System.Windows.Threading

    Imports Microsoft.Phone.Controls

    Imports Microsoft.Phone.Shell

    Imports Microsoft.Xna.Framework

    Imports Microsoft.Xna.Framework.Audio

  2. To simulate the XNA Framework, add the following code to the constructor of your MainPage class:

    ' Timer to simulate the XNA Framework game loop (Microphone is from the XNA Framework).

     

    Dim dt As New DispatcherTimer()

    dt.Interval = TimeSpan.FromMilliseconds(33)

    AddHandler dt.Tick, AddressOf dt_Tick

    dt.Start()

  3. To create a new Microphone.BufferReady event handler, add the following code:

    AddHandler microphone.BufferReady, AddressOf microphone_BufferReady

    After adding all the code mentioned in the previous steps, your constructor should look like the following:

    ''' Constructor

    Public Sub New()

        InitializeComponent()

     

        ' Timer to simulate the XNA Framework game loop (Microphone is from the XNA Framework).

        Dim dt As New DispatcherTimer()

        dt.Interval = TimeSpan.FromMilliseconds(33)

        AddHandler dt.Tick, AddressOf dt_Tick

        dt.Start()

     

        AddHandler microphone.BufferReady, AddressOf microphone_BufferReady

    End Sub

  4. To implement the BufferReady event handler, add the following code:

    Private Sub microphone_BufferReady(ByVal sender As Object, ByVal e As EventArgs)

           

            microphone.GetData(buffer)

     

            stream.Write(buffer, 0, buffer.Length)

    End Sub

    Note: While recording, this method copies the data from the microphone to a buffer. Later, it copies that buffer to a stream so that the audio can be played back again.

  5. Add the following code to create an event handler for the record button.

    Private Sub recordButton_Click(ByVal sender As Object, ByVal e As EventArgs)

        ‘ Get audio data in 1 second chunks

        microphone.BufferDuration = TimeSpan.FromMilliseconds(1000)

     

        ‘ Allocate memory to hold the audio data

        buffer = New Byte(microphone.GetSampleSizeInBytes(microphone.BufferDuration) – 1) {}

     

        ‘ Set the stream back to zero in case there is already something in it

        stream.SetLength(0)

     

        ‘ Start recording

        microphone.Start()

     

         SetButtonStates(False, False, True)

        UserHelp.Text = “record”

        StatusImage.Source = microphoneImage

    End Sub

      

    Note: This method will start capturing the audio. It also allocates memory to hold the audio for 1 second. 

  6. Add the following code to create an event handler for the stop button. This method will stop capturing the audio. 
    Private Sub stopButton_Click(ByVal sender As Object, ByVal e As EventArgs)
    

         If microphone.State = MicrophoneState.Started Then

            ' In RECORD mode, user clicked the

            ' stop button to end recording

            microphone.Stop()

        ElseIf soundInstance.State = SoundState.Playing Then

            ' In PLAY mode, user clicked the

            ' stop button to end playing back

            soundInstance.Stop()

        End If

     

            SetButtonStates(True, True, False)

            UserHelp.Text = "ready"

            StatusImage.Source = blankImage

    End Sub

     

  7. Add the following code to create an event handler for the play button.

    Private Sub playButton_Click(ByVal sender As Object, ByVal e As EventArgs)

            If stream.Length > 0 Then

                ‘ Update the UI to reflect that

                ‘ sound is playing

                SetButtonStates(False, False, True)

                UserHelp.Text = “play”

                StatusImage.Source = speakerImage

     

                ‘ Play the audio in a new thread so the UI can update.

                Dim soundThread As New Thread(New ThreadStart(AddressOf playSound))

                soundThread.Start()

            End If

    End Sub

      

    Note: This method will allocate a new SoundEffect object and play back the captured audio. 

Voila! Now your microphone for Windows Phone 7 is ready! You just need to build and debug the application.

Step 3 - Build and debug the application

  1. To build the application, select Build > Build Solution. The project should build without any errors.
  2. To debug the application, set the deployment target of the application to “Windows Phone 7 Emulator”. 
  3. Select Debug > Start Debugging. The emulator window is displayed. 
  4. To start recording the audio, click the Record button. 
  5. To stop recording the audio, click the Stop button. 
  6. To play back the captured audio, click the Play button. 
     

Note: To stop debugging the application, select Debug > Stop Debugging.

Finally, your microphone application for Windows Phone 7 is ready to be published into the marketplace. Now, you just need to rebuild your application for the release.

Step 4 - Rebuild in the release mode before publishing

  1. On the standard toolbar, change the configuration manager to Release
  2. To rebuild the application, select Build > Rebuild. The XAP file of the application is generated.

To submit your application to the market place, you can refer to upload your application walkthrough.

Summary

That’s it! We’ve now seen that creating a microphone application for Windows Phone 7 isn’t that tough. In fact, you’ve created it in just 4 simple steps!

You can find the full source code for the Visual Basic Silverlight Microphone application here.


The Visual Basic Team

Tags: , , , , , , ,

Internal Compiler Error when doing multi-proc compilation (/MP) on Windows XP

Posted in C++ on July 21st, 2011 by Admin

Ulzii Luvsanbat

Hi! My name is Ulzii Luvsanbat and I’m a Senior Test Lead with the Visual C++ team.

We’ve recently received multiple bug reports on VC++ 2010 compiler consistently crashing during multi-proc build on Windows XP and XP SP3 OSes.  This was a combination of the compiler and OS API issues that exhibited in internal compiler crash.  We have worked on a hotfix and have delivered it to customers who have reported the same issue on forums, MSConnect, and through escalation engineers.

The hotfix is available for download publicly, if you’re seeing this issue please feel free to patch the compiler from below links.  Thank you for your patience until we figured out what the problem was.

 

 

Thanks,
Ulzii Luvsanbat
Windows C++ Team


Visual C++ Team Blog

Tags: , , , , , ,

Adding block callbacks to the Facebook iOS SDK

Posted in IPhone App Programming on July 20th, 2011 by Admin

If you are like me and love using blocks over delegates, then these code snippets will come in handy. After learning about blocks I have come to love to use them, especially using them for callbacks rather than using the old protocol/delegate methodology. These code snippets will allow you to use blocks as callbacks over delegates.

In a previous post Facebook SDK – Posting to User News Feed I showed how to post various types of status’s to the logged in users news feed. These code snippets have been added to a forked version of the official Facebook for iOS SDK. A sample of how to use the new block callbacks can be found within the sample project from the last post.

For more information on blocks, you can refer to the Apple document discussing blocks in more detail.

Step 1: Modifying FBRequest Class for new callbacks
First we will modify the FBRequest class. There are a few simple modifications that we need to create. Within the FBRequest.h file add the following:

@property (copy) void (^FBRequestCallback)(FBRequest*, id, NSError*);
@property (nonatomic, assign)  BOOL usesBlockCallback;
 
+ (FBRequest*) getRequestWithParams:(NSMutableDictionary *)params
                         httpMethod:(NSString *)httpMethod
                           callback:(void(^)(FBRequest *request, id result, NSError *error)) _block
                         requestURL:(NSString *)url;

In the FBRequest.m file add the following code:

@synthesize FBRequestCallback = _FBRequestCallback;
@synthesize usesBlockCallback;
 
+ (FBRequest*) getRequestWithParams:(NSMutableDictionary *)params
                         httpMethod:(NSString *)httpMethod
                           callback:(void(^)(FBRequest *request, id result, NSError *error)) _block
                         requestURL:(NSString *)url
{
    FBRequest* request = [[[FBRequest alloc] init] autorelease];
    request.delegate = nil;
    request.url = url;
    request.httpMethod = httpMethod;
    request.params = params;
    request.connection = nil;
    request.responseText = nil;
    request.FBRequestCallback = _block;
 
    return request;
}

In the FBRequest class we are duplicating what they already have in the provided method but swapping out the delegate with a block. Out of personal preference I went with a single callback versus having an error and result callback. If there is no error we will be returning nil for the error parameter.

I also added a boolean property that will be used to determine which callback to use when processing the data when it has been returned from the Facebook servers.

Moving onto the – (void)handleResponseData:(NSData *)data; Method we need to add logic to pass the result request data onto the block callback.

- (void)handleResponseData:(NSData *)data {
  if ([_delegate respondsToSelector:
      @selector(request:didLoadRawResponse:)]) {
    [_delegate request:self didLoadRawResponse:data];
  }
 
    if (usesBlockCallback) {
        NSError* error = nil;
        id result = [self parseJsonResponse:data error:&amp;error];
        _FBRequestCallback(self, result, error);
    }
    else if ([_delegate respondsToSelector:@selector(request:didLoad:)] ||
             [_delegate respondsToSelector:@selector(request:didFailWithError:)])
    {
        NSError* error = nil;
        id result = [self parseJsonResponse:data error:&amp;error];
 
        if (error) {
            [self failWithError:error];
        }
        else if ([_delegate respondsToSelector:@selector(request:didLoad:)]) {
            [_delegate request:self didLoad:(result == nil ? data : result)];
        }
 
    }
}

We are using the same logic as the standard delegate methodology, except we do not need to make a separate delegate call if there is an error. Within the block we have included result and an NSError parameter. That way you can handle the error logic within the same callback.

Finally within the dealloc method we need to release the block. Since we are using the block in objective-c we can simply use [_FBRequestCallback release]; You can also use Block_release(_FBRequestCallback); but since we are using it within Objective-C we can use the standard way of releasing an object.

- (void)dealloc {
    [_FBRequestCallback release];
    [_connection cancel];
    [_connection release];
    [_responseText release];
    [_url release];
    [_httpMethod release];
    [_params release];
    [super dealloc];
}

Step 2: Adding request methods with block callbacks

We want to include two new methods to the Facebook.h class. One method is for graph API requests, and one is for the the old REST API.

In the Facebook.h add the following two methods:

- (void) requestWithGraphPath:(NSString *) _graphPath
                       params:(NSMutableDictionary*) _params
                       method:(NSString*) _method
                     callback:(void(^)(FBRequest *request, id result, NSError *error)) _block;
 
- (void) requestWithMethodName:(NSString *) _methodName
                     andParams:(NSMutableDictionary *) _params
                 andHttpMethod:(NSString *) _method
                      callback:(void(^)(FBRequest *request, id result, NSError *error)) _block;

In the Facebook.m file add the following two method implementations:

- (void) requestWithGraphPath:(NSString *) _graphPath
                       params:(NSMutableDictionary*) _params
                       method:(NSString*) _method
                     callback:(void(^)(FBRequest *request, id result, NSError *error)) _block
{
    NSString * fullURL = [kGraphBaseURL stringByAppendingString:_graphPath];
    [_params setValue:@"json" forKey:@"format"];
    [_params setValue:kSDK forKey:@"sdk"];
    [_params setValue:kSDKVersion forKey:@"sdk_version"];
    if ([self isSessionValid]) {
        [_params setValue:self.accessToken forKey:@"access_token"];
    }
 
    [_request release];
    //modify request to have block
    _request = [[FBRequest getRequestWithParams:_params
                                     httpMethod:_method
                                       callback:_block
                                     requestURL:fullURL] retain];
    [_request connect];
}
 
- (void) requestWithMethodName:(NSString *) _methodName
                     andParams:(NSMutableDictionary *) _params
                 andHttpMethod:(NSString *) _method
                      callback:(void(^)(FBRequest *request, id result, NSError *error)) _block
{
    NSString * fullURL = [kRestserverBaseURL stringByAppendingString:_methodName];
    [_params setValue:@"json" forKey:@"format"];
    [_params setValue:kSDK forKey:@"sdk"];
    [_params setValue:kSDKVersion forKey:@"sdk_version"];
    if ([self isSessionValid]) {
        [_params setValue:self.accessToken forKey:@"access_token"];
    }
 
    [_request release];
    //modify request to have block
    _request = [[FBRequest getRequestWithParams:_params
                                     httpMethod:_method
                                       callback:_block
                                     requestURL:fullURL] retain];
    [_request connect];
 
}

Once again we are duplicating the previously implemented methods by Facebook. The only difference is changing the request method. As you notice we are now using the methods we implemented in the FBRequest class.

Now that we have everything implemented that we need in the Facebook SDK we can use our awesome new block callbacks! The following snippet will return the logged in users friends!

    NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease];
    [facebook requestWithGraphPath:@"me/friends"
                                    params:params
                                    method:@"GET"
                                  callback:^(FBRequest *request, id result, NSError *error)
    {
        NSLog(@"friends %@", result);
        if ([result isKindOfClass:[NSDictionary class]]) {
            friendsList = [[result objectForKey:@"data"] retain];
            [table reloadData];
        }
 
    }];


iPhone Programming Tutorials

Tags: , , ,