Sharing images to Weixin/WeChat from an iOS app

This tutorial was updated in April 2016 with a link to the new version of the SDK, and adding whitelisting of the URL schemes required for iOS9.

Weixin (微信) is Tencent's mobile messaging product. It's highly popular in China, with hundreds of millions of users, as well as many international users who may know it by its English name WeChat. It includes both a chat feature, similar to WhatsApp, and a timeline feature similar to Path.

Tencent have a developer site in English, but the documentation is still quite sparse.

For a recent project, we needed to integrate sharing of images to Weixin.

The workflow for the user will be:

1. Create an image in the app
2. Tap a button to share to Weixin
3. The Weixin app will launch, and the user confirms they want to add the image to their "Moments".
4. The user taps a button in the Weixin app to return to our app.

STEP 1: Download and add the iOS SDK

1. Download the latest iOS SDK from the WeChat developer site. This version (which is only available on the Chinese developer site) includes 64-bit support. After unzipping you should have three files: libWeChatSDK.a, WXApi.h and WXApiObject.h

 

2.Copy WXApi.hWXApiObject.h and libWeChatSDK.a to your project folder.

3. Now in your XCode project go to File > Add Files and add the three files to your project.

STEP 2: Register for an app id

1. Register as a WeChat developer using the signup form. Once you've confirmed your email address, head to the My Apps page and tap "Register my apps"

2. Fill out the name of your app and other details. You can skip some optional fields like icon for now. Make sure you choose "Mobile app" as the app type, not Web app.

3. At the end of the process you will be given an app id which looks like wx123456789012

STEP 3: Integrate with the SDK

1. In your application:didFinishLaunchingWithOptions: method, add code to register your app. Be sure to replace wx123456789012 with the code you obtained earlier.

  1. if (![WXApi registerApp:@"wx123456789012"]) {
  2. NSLog(@"Failed to register with Weixin");
  3. }

2. After the Weixin app is launched it needs a way to re-launch your app. It does this by trying to open a URL with your app id as the protocol, for example wx123456789012://. We need to ensure we can handle these URLs, so implement these two methods:

  1. - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
  2. return [WXApi handleOpenURL:url delegate:self];
  3. }
  4. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  5. return [WXApi handleOpenURL:url delegate:self];
  6. }

3. We need to ensure that our app delegate implements WXApiDelegate, so first add WXApiDelegate to your AppDelegate.h file:

  1. @interface AppDelegate : UIResponde

and then add empty implementations of these two callbacks in the .m:

  1. - (void) onReq:(BaseReq*)req {
  2. }
  3. - (void) onResp:(BaseResp*)resp {
  4. }

4. We also need to make a change in the Info.plist to ensure we can handle these kind of URLs. Go to your target, select the Info tab and add a new URL type as follows. The identifier can be "weixin" and the URL scheme should match your app id.

4. Whitelist the WeChat URL schemes in your app by adding these lines to your Info.plist

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>wechat</string>
    <string>weixin</string>
</array>

 

5. Now let's add a method to send an image.

  1. - (void) sendImageContentToWeixin:(UIImage *)image {
  2. //if the Weixin app is not installed, show an error
  3. if (![WXApi isWXAppInstalled]) {
  4. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"The Weixin app is not installed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
  5. [alert show];
  6. return;
  7. }
  8. //create a message object
  9. WXMediaMessage *message = [WXMediaMessage message];
  10. //set the thumbnail image. This MUST be less than 32kb, or sendReq may return NO.
  11. //we'll just use the full image resized to 100x100 pixels for now
  12. [message setThumbImage:[image resizedImage:CGSizeMake(100,100) interpolationQuality:kCGInterpolationDefault]];
  13. //create an image object and set the image data as a JPG representation of our UIImage
  14. WXImageObject *ext = [WXImageObject object];
  15. ext.imageData = UIImageJPEGRepresentation(image, 0.8);
  16. message.mediaObject = ext;
  17. //create a request
  18. SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init];
  19. //this is a multimedia message, not a text message
  20. req.bText = NO;
  21. //set the message
  22. req.message = message;
  23. //set the "scene", WXSceneTimeline is for "moments". WXSceneSession allows the user to send a message to friends
  24. req.scene = WXSceneTimeline;
  25. //try to send the request
  26. if (![WXApi sendReq:req]) {
  27. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Error" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
  28. [alert show];
  29. }
  30. }

6. Add callback code. This will be called once control is returned to our app after returning from Weixin.

  1. - (void) onResp:(BaseResp*)resp {
  2. if([resp isKindOfClass:[SendMessageToWXResp class]]) {
  3. NSString *strMsg = [NSString stringWithFormat:@"Result:%d", resp.errCode];
  4. NSLog(@"Response from Weixin was: %@",strMsg);
  5. }
  6. }

STEP 4: Test!

All being well, you should now be able to share an image from your code, using something like:

  1. UIImage *test = [UIImage imageNamed:@"test.png"];
  2. [self sendImageContentToWeixin:test];
  3.  

After sharing the image, you should be returned to your app.

If you found this tutorial useful, or have any suggestions, do leave a comment!

Matt Mayer

Matt Mayer is a founder at ReignDesign. Matt is from the UK and was based in Shanghai for ten years. He is now living in Bangkok, Thailand.

29 comments

  1. This is a useful tutorial, thanks. I’m having issues getting things to work with the “Moments” feature though. Setting the scene to WXSceneTimeline causes the input dialog to pop up normally after Weixin starts, but upon sending and returning to my app the message itself doesn’t appear to be sent. It never appears in my feed. Do you notice the same?

    1. We did find about 10-20% of the time it seems like a moment post succeeded, but nothing is posted. The return code from Weixin is always 0, whether the post succeeded or not. Contacted Weixin support about this, but no reply yet. Our app is id currently being approved by Weixin, I wonder if this could be connected?

  2. Hi Matt, thanks for the reply. The app I’m working with is already approved, and with the messaging scene everything works fine. I also get the 0 result.

    If only China had an open source scene (besides cocos2d-x), there might be a Chinese ShareKit already… (not that ShareKit is particularly pretty either). I think our best hope is OS support for Weixin in iOS 6.2…

  3. HI Matt Mayer,

    Thanx For such a great tutorial. But after sharing image on moment why the screen redirect to Wechat OpenAPI Sample Demo screen. I want to redirect to my App.

  4. Hello Matt,

    Great Work Matt..!!!

    I have a one issue like After completeing the share image on moments, Application open the one popup for redirect the current app. But i get this popup but when i click on the “Back” Button, it not redirect me in the my app.

    error is like : “App Not Verified Yet”.

    Almost working fine but the issue is app not redirect from the wechat.

    Have any idea.?

    Thanks
    Jigar

  5. Hi Matt Mayer, I follow your steps exactly but it doesn’t work. I found that if I dont comment (BOOL)application: application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions function, the app will go to black screen initially. Because I use Cocos2d-iphone, I think maybe I should register my appid in other places? Is that right?

  6. Hello,

    I would like to know if it’s possible in a way to create animated gif and share them on Weixin/Wechat please ?
    I’ve tried 2, 3, 4 apps which are supposed to do that but that’s not at all working… However, I found several GIFS I got from a friend who got it with another friend, ect.
    Have you got an idea about how to proceed ?

  7. That time what happens , when i press the button to share image on wechat, i m redirected to the wechat app and when get back to my application after uploading.

    I want simply press the button to share the image and image will be shared on wechat without redirection to the wechat app.

    Is it possible..?

  8. Hi Matt,

    I implement this tutorial correctly but I can’t figured why my app isn’t called back once the user had shared on his moment. My app is approved by WeChat. Any idea ?

  9. In this Sdk found this type of error like,

    ld: warning: directory not found for option ‘-L”/Users/rahulpanch/Downloads/WeChat_SDK_sample_iOS_en/SDKSample_en/../SDKExport”‘
    ld: warning: directory not found for option ‘-L/Users/gracoli/Desktop/WeChat_SDK_sample_iOS_en/SDKExport’
    ld: library not found for -lWeChatSDK
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

  10. Hi matt,
    I have weixn id(we123456677), and successfully sharing the image in my app… But the bottom of the image, it displayed “the app is not verified”. Why its happening ?

  11. Hello, Thanks for this nice helpful material. I have a question If you know anything about it your help will be appreciable for me. Can we send message to a particular contact instead of opening user what’s app contact list??

  12. Great tutorial man.

    It’ll be nice of you to mention that whether the WeChat sdk will work or not if the native WeChat app is NOT installed on the iPhone.

    Cheers.

  13. Hi Matt.

    I have successfully shared image on wechat. But i need to share image as well as some text. i have use your code I have toggled “req.bText = YES;” as well but i am not able to share text along with image.

    Can you tell my any specific reasons

Leave a Reply

Your email address will not be published. Required fields are marked *