The Mobile Galaxy The New Mobile Era Has Come | Mobile – A Time To Remember

27Jul/120

Backbone model dynamic url method

-- Backbone Model /View -- when model changed, trigger view refresh ;

--Dynamic refresh a  grid/ table by different url;

Main.MappingsData = Backbone.Model.extend({
	defaults:{
		query:'',
		Mappings:null
	},
	url:"/dummy.json",
	
	  refetch: function(options){
		    _.bindAll(this, "refreshUserData");
		    console.log("refetch.....");
	        console.log(this);
	        this.fetch({success:this.refreshUserData, error:this.errorUserData});
	    },
	    
	  initialize: function(options){
		    _.bindAll(this, "refreshUserData");
		    console.log("Initialize.....");
	        console.log(this);
	        this.fetch({success:this.refreshUserData, error:this.errorUserData});
	    },
	  refreshUserData: function(data){
		    console.log("refreshUserData.....");
	        console.log(data);
	        console.log(this);
	    },

	    errorUserData: function(data){
	        alert("ERROR: Fetching user data");
	    }	 
	});
	
Main.HomeView = Backbone.View.extend({
  tagName: 'div',
  events: {
	    "click #loadmore": "loadMore"
	  },
	  
  initialize: function() {
    _.bindAll(this, 'render');
    this.model.bind('change', this.render);
  },

  render: function() {
    var compiledHome = Handlebars.compile($("#home-template").html());
    var sampleData =this.model.toJSON();
	console.log("sampleData...");
	console.log(sampleData);
    $(this.el).html(compiledHome(sampleData));
    return this;
  },
    loadMore:function(){
      	this.model.trigger('clear', this);
    	this.model.url="/dummy2.json";
         var self = this;
         this.model.fetch({
             success:function() {
            	 console.log(this.model.url);   
             }
         });
    }  
});

	var dummy= new Main.MappingsData();

    var view =new Main.HomeView({model:dummy}));

 

 

Share
15May/120

How to change uppercase sentences to mixed text in Java?

/**
 *
 */
package com.go2log.kevin;
import java.text.BreakIterator;
import java.util.Locale;
/**
 * @author Kevin Sun
 *
 */
public class FormatParagraph {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String paragraph =
                "LINE BOUNDARY ANALYSIS DETERMINES WHERE A TEXT " +
                "STRING CAN BE BROKEN WHEN LINE-WRAPPING. THE " +
                "MECHANISM CORRECTLY HANDLES PUNCTUATION AND " +
                "HYPHENATED WORDS. ACTUAL LINE BREAKING NEEDS TO " +
                "ALSO CONSIDER THE AVAILABLE LINE WIDTH AND IS " +
                "HANDLED BY HIGHER-LEVEL SOFTWARE. ";

        BreakIterator iterator =
                BreakIterator.getSentenceInstance();

        String sentences = paragraphformatter(iterator, paragraph.toUpperCase());
        System.out.println("New Sentences: " + sentences);
    }

    private static String paragraphformatter(BreakIterator bi, String source) {
        StringBuffer formattedString = new StringBuffer();
        bi.setText(source);

        int lastIndex = bi.first();
        while (lastIndex != BreakIterator.DONE) {
            int firstIndex = lastIndex;
            lastIndex = bi.next();

            if (lastIndex != BreakIterator.DONE) {
                String sentence = source.substring(firstIndex, lastIndex);
                System.out.println("sentence = " + sentence);
                formattedString.append(toProperCase(sentence.toLowerCase()));

            }
        }
        return formattedString.toString();
    }

    private static String toProperCase(String name) {
        return name.substring(0, 1).toUpperCase() +
                   name.substring(1).toLowerCase();
    }
}

Result:
sentence = LINE BOUNDARY ANALYSIS DETERMINES WHERE A TEXT STRING CAN BE BROKEN WHEN LINE-WRAPPING.
sentence = THE MECHANISM CORRECTLY HANDLES PUNCTUATION AND HYPHENATED WORDS.
sentence = ACTUAL LINE BREAKING NEEDS TO ALSO CONSIDER THE AVAILABLE LINE WIDTH AND IS HANDLED BY HIGHER-LEVEL SOFTWARE.
New Sentences: Line boundary analysis determines where a text string can be broken when line-wrapping. The mechanism correctly handles punctuation and hyphenated words. Actual line breaking needs to also consider the available line width and is handled by higher-level software.
Share
Tagged as: , No Comments
26Apr/120

EU Cookie Directive Solutions

Massive thanks to Greg Rouchotas from CivicUK.

What you need for EU LAW COMPLIANCE:

  • Access to the template files that make your website work or if your on Drupal 7 or WordPress  you get easy install mods! (you can ignore the rest of this guide)
  • Jquery 1.4.4 or above called into your templates (Drupal 6 users see this fix, Method 3 or 4 patch your jquery mod and upload latest jquery)
  • CookieControl-3.0.min.js from the CivicUK website (DirectLink)
For Piwik – NO COOKIE Tracking
  • Access to deploy a new MYSQL Database for Piwik to use
  • A different set of code to integrate CookieControl with GA and Piwik (See bottom of  this guide)

Then all you need to do is paste the below code  before your </head> of your websites template depending on your templates this may be your header template file or at the top of your Index file.

<script type=”text/javascript”>
function ccAddAnalytics(){
$.getScript(‘http://www.google-analytics.com/ga.js’, function() {
var GATracker = _gat._createTracker(‘YOUR GA TRACKING CODE UA-00000‘);
GATracker._trackPageview();
} );

</script>

<script src=”http://www.geoplugin.net/javascript.gp” type=”text/javascript”></script>
<script src=”http://pathtoCookieControlScript/cookieControl-3.0.min.js” type=”text/javascript”></script>
<script type=”text/javascript”>//<![CDATA[
cookieControl({
text:'<p>This site uses cookies to store information on your computer. Some of these cookies are essential to make our site work and others help us to improve by giving us some insight into how the site is being used.</p><p>By using our site you accept the terms of our <a href="http://www.YOURPRIVACYURL">Privacy Policy</a>.</p>',
position:'right', // or right
shape:'diamond', // or diamond
startOpen:true,
autoHide:60000,
onAccept:function(){ccAddAnalytics()},
onCookiesAllowed:function(){ccAddAnalytics()},
onCookiesNotAllowed:function(){
},
countries:'United Kingdom' // Or supply a list ['United Kingdom', 'Greece']
});
//]]>
</script>

Piwik Cookie-less Tracking

I’m not going to run through installing Piwik as it’s well covered on their website, in all it took me 15 minutes to install and configure it onto our servers.

One you have it on your server you need to use the below code to not only call Google Analytic’s but also Piwik, just as with the basic code above this needs to go before the </head>

<script type=”text/javascript”>
function ccAddAnalytics(){
$.getScript(‘http://www.google-analytics.com/ga.js’, function() {
var GATracker = _gat._createTracker(‘YOUR GA TRACKING CODE UA-00000”);
GATracker._trackPageview();
} );

$.getScript(‘http://LOCATION OF PIWIK ON YOUR SERVER/piwik/piwik.js’, function(){
var pkBaseURL = ((“https:” == document.location.protocol) ? “http://LOCATION OF PIWIK ON YOUR SERVER/piwik” : “http://LOCATION OF PIWIK ON YOUR SERVER/piwik”);
var piwikTracker = Piwik.getTracker(pkBaseURL + “piwik.php”, 1);
piwikTracker.trackPageView();
piwikTracker.enableLinkTracking();
});

};

</script>

<script src=”http://www.geoplugin.net/javascript.gp” type=”text/javascript”></script>
<script src=”http://pathtoCookieControlScript/cookieControl-3.0.min.js” type=”text/javascript”></script>
<script type=”text/javascript”>//<![CDATA[
cookieControl({
text:'<p>This site uses cookies to store information on your computer. Some of these cookies are essential to make our site work and others help us to improve by giving us some insight into how the site is being used.</p><p>By using our site you accept the terms of our <a href="http://http://www.YOURPRIVACYURL">Privacy Policy</a>.</p>',
position:'right', // or right
shape:'diamond', // or diamond
startOpen:true,
autoHide:60000,
onAccept:function(){ccAddAnalytics()},
onCookiesAllowed:function(){ccAddAnalytics()},
onCookiesNotAllowed:function(){
var doc_title=document.title;
var doc_ref=document.referrer;
$('body').append("<img src=\"http://LOCATION OF PIWIK ON YOUR SERVER/piwik/piwik.php?idsite=1&amp;rec=1&amp;action_name="+doc_title+"&amp;urlref="+doc_ref+"\" style=\"border:0\" />");
},
countries:'United Kingdom' // Or supply a list ['United Kingdom', 'Greece']
});
//]]>
</script>

Now clear your cache and reload the site, head over to your Piwik login and you should see data from all your users who don’t accept Cookies, check in your Google Analytic’s Real Time Results when you click the Accept button and you should see yourself appear in Real Time Results within a few seconds.

 

Other options:

1. Wolf Software provide a number of solutions to assist with compliance. Demos can be located at:

http://cookies.dev.wolf-software.com (Simple one line GA drop in solution)

http://jpecr.dev.wolf-software.com (a universal solution with multiple configuration options)

2. cookie-warning

3. UK & European Cookie Law Solution (Free Script) 

Resource

1. Geoplugin--Get country by IP

2. GeoLite Country-Country Information  Database

3. Preventing Google Analytics Cookies

<script type="text/javascript">
if (_cookieOK.accepted){
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-222592-4']);
  _gaq.push(['_trackPageview']);
  (function() {
    var ga = document.createElement('script');
    ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ?
       'https://ssl' : 'http://www') +
       '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(ga, s);
  })();
}
</script>
The relevant changes to the stock script are highlighted in red. At the moment the _cookieOK variable only has the accepted property, but we may well add more.

Demo & sample

1. ba.com

2. bt.com(has implemented quite a comprehensive response to the cookie law today, if you’re in need of some more inspiration…)

3. EU cookie law: three approaches to compliance(Modal dialogue,Status bar,Warning bar)

4. http://cookieok.eu/

 

Share
Filed under: iPhone No Comments
28Jan/120

Get rid of Desktop.ini files

Desktop.ini is a Windows XP system file that is created by the operating system itself for storing information about customized folders(if you have customized the display of a folder in any way, such as changing its icon or manner of display)and it also consists of the information about the folder is shared or not .By deleting these files you will not get into any troubles.

You can get rid of this desktop.ini files in two ways one is by using registry editor(regedit) and the other is using folder options first i will discuss about how to remove them using registry editor

  1. Click on  Start-> Run type Regedit in it and press Enter
  2. Navigate to this key HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun
  3. In the right pane delete Kernel32 value
  4. Now navigate to this keyHKEY_CURRENT_USERSoftwareMicrosoftOffice9.0OutlookOptionsMail
  5. In the right pane, delete the values
    Compose Use Stationery
    Stationery Name
    Wide Stationery Name
  6. Navigate to the key HKEY_CURRENT_USERSoftwareMicrosoftOffice9.0OutlookOptionsMail
  7. In the right pane, delete the value
    EditorPreference
  8. Navigate  and delete these subkeys also:HKEY_CLASSES_ROOTdllFileShell
    HKEY_CLASSES_ROOTdllFileShellEx
    HKEY_CLASSES_ROOTdllFileScriptEngine
    HKEY_CLASSES_ROOTdllFileScriptHostEncode
  9. Now exit from the register and delete the desktop.ini files in your memory.
  10. Restart your computer and you are done.

Second method to get rid of these Desktop.ini files is using folder options which is easier than above mentioned method

  1. Go to  Folder Option
  2. Click on the View tab.
  3. Check  “Do not show hidden files and folders”.
  4. Check  to “Hide protected operating system files (recommended)”.
  5. Click OK.

Now check your folders and you will not find any Desktop.ini  files.

Share
Filed under: Other No Comments
20Jan/120

Mac OS Lion, Slow Safari browsing but everything else normal.

From: https://discussions.apple.com/thread/3199056?start=0&tstart=0

SOLUTION: Hopefully this helps someone else out.

 

Close Safari, then open Terminal. Type:

 

chflags nohidden ~/Library/

 

You will then be able to see ~/Library in the Finder. Goto ~/Library/Caches/com.apple.safari/. Delete the Cache.db file. Restart Safari and you should be all set. For some reason the "Reset Safari" and "Empty Cache..." don't seem to be working...

Share
Filed under: Other No Comments
10Dec/110

Got Git? HOWTO git and github

Thanks to Steven Bristol .

From :http://lesseverything.com/blog/archives/2008/03/25/got-git-howto-git-and-github/

Share
6Dec/110

iPhone Program Crashes and Stability Issues

If you’re running into frequent iPhone program crashes, here are some tips for getting better stability.

Application memory management issues

Generally, it caused by memory management, such as a instance un-alloc, released, un-expected copy. This kind issues is easy to find through unit test and functionality test.

Apple firmware compatibility issues

As the IOS version change, API maybe different, sometimes it is serious and kill the app.

For example:

In IOS 5, the following statement is fine:

UIBarButtonItem* rightBtn= [[UIBarButtonItem alloc] initWithTitle:@"Upload" style:UIBarButtonItemStylePlain target:self action:@selector(upload)];

rightBtn.tintColor=[UIColor redColor]; // it will crash in IOS 4.0

In IOS 4.2.1

-(void)finishedTakePicture:(UIImage*)img{

_stillimage =[img copy]; // This run fine in IOS 4.2.1, but it will crash in IOS 4.1

// solution:   [_stillimage setValue:img forKey:@"image"];

}

So checking each IOS version API difference is most important to avoid random crash. generally this kind issues can not be found through unit test or simulator debug.

How to automatically check API diff maybe a interesting topic for iPhone testing.

For getting better stability, we have to do testing through three aspects:

Unit test and functionality test

Memory management test

IOS version compatibility test
PS: A list of all firmware:

Share
25Nov/110

Memory Management Advice – iphone

I am a little unclear about some of the conventions in memory management. I have tried to follow Slick and Duncan's advice and follow this style:

in .h

Class *_var

@property (nonatomic, retain) Class *var

in .m@synthesize var = _var;When assigning the variable

either (for example with UITextView):

self.var = [[[UITextView alloc] initWithFrame:(such and such frame)] autorelease];

(autorelease to avoid two retains)

or

UITextView *tempTextView = [[UITextView alloc] initWithFrame:(so on and so so)];
self.var = tempTextView;
[tempTextView release];

In dealloc

self.var = nil; (does the release automatically due to synthesize)

So, assuming I am doing this right, the question comes up in what I do when I am working with these variables. Do I use the instance variable or property when working with the variable in non "self.var = " purposes.

for instance:

If var is a UITextView, Do I use:

self.var.userInteractionEnabled = NO;
self.var.text = @"Some Text";

OR

_var.userInteractionEnabled = NO;
_var.text = @"Some Text";

Basically,

When is the property accessed when changing the "sub properties" vs. the instance variable. It seems like both work but I assume that one would have a preferred way above another.

I was under the impression that I should only call the property when directly assigning. e.g.

self.var = something;

Additionally, when adding a subView to a view (assuming a UITextView var), would I say:

[self.view addSubView: self.var];

or

[self.view addSubview:_var];

btw, I've color coded Instance Variables as Slick suggested in red but I am confused as it seems like everything shows up as an instance variable (including self.var) in red. The only time something shows up not red is like:

[something setSomething:self.var];

Where "var" is not red.

Otherwise:

self.var =

or

_var =

var is red.

I feel like this is a huge fundamental thing I am missing and although I have created a great number of successful apps, I keep having minor bugs haunt me that are associated with memory problems. All the tutorials you follow assign instance variables and properties with the same exact name so it isn't clear what is going on and why it works.

Thanks!
James

Share
21Nov/110

What is MailCore?

MailCore is a Cocoa framework designed to ease the pain of dealing with e-mail protocols by adding a nice Objective-C/Cocoa interface to the C library Libetpan!. MailCore makes the process of sending e-mail easy by hiding the nasty details like MIME composition from you. Instead, there is a nice interface for composing messages and then there is a single method required to send the message. Checking e-mail on an IMAP server is a more complex beast, but MailCore makes the job much simpler but presenting everything as a set of abstract objects like Messages, Folders and Accounts. Note, however, that MailCore is not multithreaded so any calls made will potentially block and not every IMAP detail is abstracted away. Also, MailCore stores everything in memory so if you want to save state to disk it has to be done by hand.

 

Sending E-mail

Sending e-mail with MailCore is very easy, it takes care of all the details like MIME encoding, and the SMTP protocol. First, start by creating a CTCoreMessage instance. Then set the subject, body, from, and atleast one to, bcc, or cc recipient. One detail to note is that the to, cc, bcc attributes take an NSSet of CTCoreAddress recipients.

CTCoreMessage *testMsg = [[CTCoreMessage alloc] init];
[testMsg setTo:[NSSet setWithObject:[CTCoreAddress addressWithName:@"Monkey" email:@"monkey@monkey.com"]]];
[testMsg setFrom:[NSSet setWithObject:[CTCoreAddress addressWithName:@"Someone" email:@"test@someone.com"]]];
[testMsg setBody:@"This is a test message!"];
[testMsg setSubject:@"This is a subject"];

Once the message attributes have been set, all that is left is sending the message usingCTSMTPConnection:

[CTSMTPConnection sendMessage:testMsg server:@"mail.test.com" username:@"test" password:@"test" port:25 useTLS:YES shouldAuth:YES];
[testMsg release];

That's all

 

Working with IMAP

Working with IMAP through MailCore is quite easy. First you need to instantiate aCTCoreAccount object and establish a connection like so:

CTCoreAccount *account = [[CTCoreAccount alloc] init];
[account connectToServer:@"mail.theronge.com" port:143 connectionType:CONNECTION_TYPE_PLAIN authType:IMAP_AUTH_TYPE_PLAIN login:@"test" password:@"none"];

If by any chance it fails to make a connection an exception will be thrown. Now that we have a connection to the server we can go ahead and get a list of folders. Note: I use the term folder in place of mailbox; the IMAP spec uses the term mailbox but I get that confused with account.

NSSet *subFolders = [account subscribedFolders];

If we take a look at the resulting NSSet, we see that what is returned is a set of NSStrings with folder path's.

<NSCFSet: 0x309d60> (INBOX.Test.Test22, INBOX, INBOX.TheArchive, INBOX.Test, INBOX.Trash)

We can use one of those strings to create a CTCoreFolder object or we can just pass in a path, for example this sets up a connection to the INBOX on the server.

CTCoreFolder *inbox = [account folderWithPath:@"INBOX"];

Now that we have a connection to a folder we can start to do more interesting things, like we can get a set of the messages in the particular folder, or we can delete the folder, or remove the folder from the subscribed list, check the CTCoreFolder for more information. For this particular example I am going to get a list of the messages in the INBOX (0 as the end index indicates that the entire inbox should be loaded).

NSSet *messageList = [inbox messageListFromIndex:1 toIndex:0];

Like the with folders, what is returned is a set of NSString's containing unique message identifiers (UID).

<NSCFSet: 0x309d60> (1142229815-5, 1142229815-6, 1142229815-7, 1142229815-8, 1142229815-10, 1142229815-1, 1142229815-9, 1142229815-2, 1142229815-11, 1142229815-3, 1142229815-4)

You might be wondering about the parameter to messageListFromIndex: now, it's exists because of a limitation of IMAP. IMAP was designed to be a protocol where you would always be connected to the server, it wasn't until later that people got the idea using IMAP as an offline protocol. Therefore, IMAP generally returns the entire list of message UID's, but this can be very time consuming for very large folders, and by a large folder I'm talking over 5000 messages. To download only new messages and not every message each time, you can save the last message UID you received. Since you have the last message UID you know the next UID has to be one after it. For example, if you receive the UID 1142229815-4 then you know the next UID has to be 1142229815-5. So if you pass 1142229815-4 into messageListFromIndex: it will only retrieve message with a higher UID.

While UID's are not supposed to change, a folder can change the message UID's on rare occasions. It's important to make sure that the cached UID"s are still valid by using the isUIDValid method. If a bad UID was used there is potential for data loss, since the former UID might not reference the message you intend on deleting. If you save a UID, you should make sure that the server is still using the same UID, otherwise start over by passing nil into messageListFromIndex.

Now back to working with messages, to retrieve with a particular message you need to use the method messageWithUID inside of CTCoreFolder. The resulting object will be of typeCTCoreMessage, from there you can retrieve the subject, body and other things by using the message object.

Share
21Nov/110

Capture IOS Screen code

1.
UIGraphicsBeginImageContextWithOptions(pageView.page.bounds.size, YES, zoomScale);
        [pageView.page.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *uiImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
2.
- (UIImage *) glToUIImage {
    
    DWScrollView *pageView = [self getActivePageView];
       pageView.page.backgroundColor = [UIColor clearColor];
  //  self.backgroundColor=[UIColor clearColor];
    NSInteger myDataLength = 320 * 308 * 4;
    
    // allocate array and read pixels into it.
    GLubyte *buffer = (GLubyte *) malloc(myDataLength);
    glReadPixels(0, 0, 320, 308, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    
    // gl renders "upside down" so swap top to bottom into new array.
    // there's gotta be a better way, but this works.
    GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
    
    for(int y = 0; y <308; y++)
    {
        for(int x = 0; x <320 * 4; x++)
        {
            if(buffer[y* 4 * 320 + x]==0)
                buffer2[(307 - y) * 320 * 4 + x]=1;
            else
                buffer2[(307 - y) * 320 * 4 + x] = buffer[y* 4 * 320 + x];
        }
    }
    
    // make data provider with data.
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);
    
    // prep the ingredients
    int bitsPerComponent = 8;
    int bitsPerPixel = 32;
    int bytesPerRow = 4 * 320;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    
    // make the cgimage
    CGImageRef imageRef = CGImageCreate(320, 308, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
    
    // then make the uiimage from that
    UIImage *myImage = [UIImage imageWithCGImage:imageRef];
    UIImageWriteToSavedPhotosAlbum(myImage, nil, nil, nil);
    return myImage;
}

3.
// get screen
- (void)grabScreen {
    unsigned char buffer[320*480*4];
    glReadPixels(0,0,320,480,GL_RGBA,GL_UNSIGNED_BYTE,&buffer);
    
    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, &buffer, 320*480*4, NULL);
    CGImageRef iref = CGImageCreate(320,480,8,32,320*4,CGColorSpaceCreateDeviceRGB(),kCGBitmapByteOrderDefault,ref,NULL,true,kCGRenderingIntentDefault);
    CGFloat width = CGImageGetWidth(iref);
    CGFloat height = CGImageGetHeight(iref);
    size_t length = width*height*4;
    uint32_t *pixels = (uint32_t *)malloc(length);
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, 320*4, CGImageGetColorSpace(iref), kCGImageAlphaLast | kCGBitmapByteOrder32Big);
    CGContextTranslateCTM(context, 0.0, height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), iref);
    CGImageRef outputRef = CGBitmapContextCreateImage(context);
    UIImage *outputImage = [UIImage imageWithCGImage:outputRef];
    
    UIImageWriteToSavedPhotosAlbum(outputImage, nil, nil, nil); 
    
    CGContextRelease(context);
    CGImageRelease(iref);
    CGDataProviderRelease(ref);
} 
4.
CGImageRef UIGetScreenImage();
void SaveScreenImage(NSString *path)
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    CGImageRef cgImage = UIGetScreenImage();
        void *imageBytes = NULL;
        if (cgImage == NULL) {
                CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
                imageBytes = malloc(320 * 480 * 4);
                CGContextRef context = CGBitmapContextCreate(imageBytes, 320, 480, 8, 320 * 4, colorspace, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);
                CGColorSpaceRelease(colorspace);
                for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
                        CGRect bounds = [window bounds];
                        CALayer *layer = [window layer];
                        CGContextSaveGState(context);
                        if ([layer contentsAreFlipped]) {
                                CGContextTranslateCTM(context, 0.0f, bounds.size.height);
                                CGContextScaleCTM(context, 1.0f, -1.0f);
                        }
                        [layer renderInContext:(CGContextRef)context];
                        CGContextRestoreGState(context);
                }
                cgImage = CGBitmapContextCreateImage(context);
                CGContextRelease(context);
        }
    NSData *pngData = UIImagePNGRepresentation([UIImage imageWithCGImage:cgImage]);
    CGImageRelease(cgImage);
        if (imageBytes)
                free(imageBytes);
    [pngData writeToFile:path atomically:YES];
    [pool release];
}

5.
  + (UIImage *)imageWithScreenContents
{
     CGImageRef cgScreen = UIGetScreenImage();
     if (cgScreen) {
         UIImage *result = [UIImage imageWithCGImage:cgScreen];
         CGImageRelease(cgScreen);
         return result;
     }
     return nil;
}
Share