In my app , I check [UIPasteboard generalPasteboard].changeCount in
- (void)applicationDidBecomeActive:(UIApplication *)application
But I found that every time I press iPhone's Lock Screen button , this applicationDidBecomeActive will be called , and the changeCount value will alway be 0 this time
Why the applicationDidBecomeActive called for Lock Screen ? (My OS version is iOS16.1)
In my situation , I use this code to avoid the paste board check in locking screen(In fact ,the pasteboardChangeCount will be zero when applicationDidBecomeActive is called in Lock Screen )
- (void)checkPasteBoard
{
static NSInteger lastCount = 0;
NSInteger pasteboardChangeCount = [UIPasteboard generalPasteboard].changeCount;
if (lastCount != pasteboardChangeCount && pasteboardChangeCount != 0)
{
lastCount = pasteboardChangeCount;
}
else
{
return;
}
Related
I'm new to make iPhone App with Objective-c
I want to make the App which sends a notification when iPhone screen is locked(Pressed Lock button)
How can I make this app?
I'm trying to make it using "applicationWillSuspend", but
/*----------------------------------------*/
- (void)applicationWillSuspend
{
NSLog(#"WillSuspend");
}
/*----------------------------------------*/
This code doesn't work
I'm not sure when applicationWillSuspend is called
Please, give me some knowledge
#import "AppDelegate.h"
#import <notify.h>
#interface AppDelegate ()
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// iOS8 Notification permit
if ([UIApplication
instancesRespondToSelector:#selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication]
registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound
categories:nil]];
}
return YES;
int notify_token;
notify_register_dispatch("com.apple.springboard.lockstate",
¬ify_token,
dispatch_get_main_queue(),
^(int token)
{
uint64_t state = UINT64_MAX;
notify_get_state(token, &state);
if(state == 0) {
NSLog(#"unlock device");
} else {
NSLog(#"lock device");
}
}
);
}
Import this in app delegate #import <notify.h>
Write this piece of code in didFinishLaunchingWithOptions
int notify_token;
notify_register_dispatch("com.apple.springboard.lockstate",
¬ify_token,
dispatch_get_main_queue(),
^(int token)
{
uint64_t state = UINT64_MAX;
notify_get_state(token, &state);
if(state == 0) {
NSLog(#"unlock device");
} else {
NSLog(#"lock device");
}
}
);
So once your iPhone gets locked, you will get "lock device" as log. So you can write your code in that block. This will help you.
You can't do that on the iPhone.
But through, Darwin notifications. You can detect the event when the device is locked by "com.apple.springboard.lockcomplete".
Have a look at these links too hopefully it may help you:
1) Lock Unlock events iphone
2) How can I detect screen lock/unlock events on the iPhone?
applicationWillSuspend method doesn't exist natively, but in the AppDelegate.m you can play with applicationWillResignActive and applicationWillResignActive these methods will be called when the user hits the home button and the app will go to the background (here you can keep your connection live, but you should read the apple documentation regarding background tasks because your connection cannot be live forever if the app remains in the background. There are other ways to keep your app up to date like update on push notification etc):
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
and this method will be called when the app will get terminated (closed completely from multitasking).
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
You can handle your connections within these methods.
I'm creating an app that displays monitors iBeacon regions, which means that when the device is locked and within range of a beacon, my app's icon is shown on the lock screen in the bottom left.
Is there any way that I can detect if my app is launched through this lock screen icon, and run some code?
When the icon appears, it indicates that a beacon region has been entered. The CLLocationManager delegate's didEnterRegion method will be called when the icon first appears.
You can put custom code there to set a flag indicating the icon appeared.
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
_iconShown = YES;
}
Then, when your app comes to the foreground, you can check this flag to see if it is set, and execute your custom logic:
- (void)applicationWillEnterForeground:(UIApplication *)application {
if (_iconShown) {
_iconShown = NO;
// Put custom logic here for launching from the icon
}
}
hmm, there is an alternative way, that you can handle it, just create an variable self.backgroundedToLockScreen like:
- (void)applicationWillEnterForeground:(UIApplication *)application {
if (self.backgroundedToLockScreen) {
... // app was backgrounded to lock screen
} else {
... // app was backgrounded on purpose by tapping the home button or switching apps.
}
self.backgroundedToLockScreen = NO;
}
and
- (void)applicationWillEnterForeground:(UIApplication *)application {
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (UIApplicationStateInactive == state || // detect if coming from locked screen (iOS 6)
self.backgroundedToLockScreen) // detect if backgrounded to the locked screen (iOS 7)
{
... // app is coming from or was backgrounded to lock screen
} else {
... // app was backgrounded on purpose by tapping the home button or switching apps
}
self.backgroundedToLockScreen = NO;
}
Hope this could be useful for you.
According to the Apple Docs, in order to find out if a user tapped on your push notification you are supposed to check the applicationState in application:didReceiveRemoteNotification:
If the value is UIApplicationStateInactive, the user tapped the action button; if the value is UIApplicationStateActive, the application was frontmost when it received the notification.
I have found that this is not always true. For example:
Double-tap the home button to reveal the system tray and enter "fast app switching mode", your application slides up to reveal other running applications and your app is put into the inactive state (even though it's still mostyle visible). If you receive a push notification in this mode your app delegate will still receive the application:didReceiveRemoteNotification: and at this point your applicationState is UIApplicationStateActive. According to the docs you should treat it like the user tapped the alert... but in this case they didn't. Not only that, the user didn't even see the push notification (possibly because the top of your application is cut off in this mode).
Does anyone know of a way to detect being in 'fast app switching mode' or handle the notification correctly?
I was able to fix it myself with some nifty checks...
Essentially the key to this whole thing is
-(void)applicationDidEnterBackground:(UIApplication *)application;
This method isn't called when you enter fast app switching (or control center) so you need to setup a check based on it.
#property BOOL isInBackground;
#property (nonatomic, retain) NSMutableArray *queuedNotifications;
And when you receive a notification...
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIApplicationState appState = application.applicationState;
// Check if we're in this special state. If so, queue the message up
if (appState == UIApplicationStateInactive && !self.isInBackground) {
// This is a special case in which we're in fast app switching or control center
if (!self.queuedNotifications) {
self.queuedNotifications = [NSMutableArray array];
}
// Queue this to show when we come back
[self.queuedNotifications addObject:userInfo];
}
}
And then when we come back...
- (void)applicationDidBecomeActive:(UIApplication *)application {
application.applicationIconBadgeNumber = 0;
if (!self.isInBackground) {
// Show your notifications here
// Then make sure to reset your array of queued notifications
self.queuedNotifications = [NSMutableArray array];
}
}
One more thing you may want to do is check for this special case of going to fast app switching and the user going somewhere else. I do this just before setting the isInBackground BOOL. I choose to send them as local notifications
-(void)applicationDidEnterBackground:(UIApplication *)application {
for (NSDictionary *eachNotification in self.queuedNotifications) {
UILocalNotification *notification = [self convertUserInfoToLocalNotification:eachNotification];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
self.queuedNotifications = [NSMutableArray array];
self.isInBackground = YES;
}
I am developing an iphone app with phonegap and jquery mobile. When the app is closed and enters the background mode, I am trying to blur the screen so that when the app is resumed, sensitive data on the screen will be blurred out.
I am trying to do this in the on pause event, but it looks like IOS is taking a screenshot of the app before the pause event, thus my blur code does not get captured in the screen shot that IOS shows when resuming the app.
Does anyone have any ideas on how to get this to work?
The pause event is triggered by UIApplicationDidEnterBackgroundNotification, which means that apps already in the background the screen shot has been taken. Is there event before this that I can hook into?
This will be even more important in ios7 when the screen shot is shown when you double click the home button. In ios6 it is only shown for a split second while the app resumes and is loaded.
Thanks!
Code that I have tried in pause and resume phonegap listeners.
// listen for events
document.addEventListener("resume", onResume, false);
document.addEventListener("pause", onPause, false);
// show passcode if enabled, maybe even re-fresh app to start new session and clean up memory issues?
function onResume() {
// unblur page
var filterVal = 'blur(0px)';
$('.ui-page').delay(1000).css('webkitFilter', filterVal);
}
function onPause() {
var filterVal = 'blur(10px)';
$('.ui-page').css('webkitFilter', filterVal);
}
The phonegap plugin cordova-plugin-privacyscreen does the trick - it replaces the view with the splash image prior to backgrounding and clears it afterwards.
https://www.npmjs.com/package/cordova-plugin-privacyscreen
I am facing the same problem here. If your app is enabled multitasking. You can change the native code in appdelegate by adding the current code
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(#"Application Did Enter Background");
self.viewController.webView.hidden = YES;
NSString *splashImage;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
splashImage = #"Default-Portrait~ipad.png";
}
else {
splashImage = #"Default~iphone.png";
}
UIImageView *splash = [[UIImageView alloc]initWithFrame:[self.window frame]];
[splash setImage:[UIImage imageNamed:splashImage]];
[self.window addSubview:splash];
}
- (void) applicationDidBecomeActive:(UIApplication *)application {
NSLog(#"Application Did Become Active");
if([[self.window subviews] count]>1) {
[NSThread sleepForTimeInterval:0.3];
[[[self.window subviews] lastObject] removeFromSuperview];
}
self.viewController.webView.hidden = NO;
}
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(#"Application Did Resign Active");
self.viewController.webView.hidden = YES;
NSString *splashImage;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
splashImage = #"Default-Portrait~ipad.png";
}
else {
splashImage = #"Default~iphone.png";
}
UIImageView *splash = [[UIImageView alloc]initWithFrame:[self.window frame]];
[splash setImage:[UIImage imageNamed:splashImage]];
[self.window addSubview:splash];
}
However, make sure your app is support Multitasking. Otherwise this won't work due to the applicationDidEnterBackground is NOT called when the multitasking feature is turned off. And the function(applicationWillTerminate) which should be called and it is NOT called neither.
In this application that I'm trying to make, I use push notifications. This part works just fine. When I send a notification I also add a badge to the app icon. The problem is when I lunch the application it should disappear again, but it does not.
-(IBAction)Push{
NSMutableDictionary *data = [NSMutableDictionary dictionary];
[data setObject:#"Numfeud: Troels made a move!" forKey:#"alert"];
[data setObject:[NSNumber numberWithInt:1] forKey:#"badge"];
[data setObject:#"bar" forKey:#"foo"];
[PFPush sendPushDataToChannelInBackground:#"GameChannel2" withData:data];
}
In the application didFinishLaunchingWithOptions I try to set badge to 0 in this way:
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
How can I clear the application icon badge?
If your app becomes active again and is still in the background you should reset the badge count in -applicationDidBecomeActive: as well:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
If your app is still running in the background -application:didFinishLaunchingWithOptions: won't be called.
Likely, -application:didFinishLaunchingWithOptions: is not being called, because your app is still running in the background. In order to remove the badge count when the app is launched from the background you'll have to reset the badge number in -applicationWillEnterForeground:, too.
In Swift and In AppDelegate
func applicationDidBecomeActive(_ application: UIApplication) {
application.applicationIconBadgeNumber = 0
}
You can use this codes also.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
application.applicationIconBadgeNumber = 0;
}
or In a specific ViewController
- (void)awakeFromNib {
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
Maybe call it in applicationWillResignActive (in AppDelegate.m):
-(void)applicationWillResignActive:(UIApplication *)application{
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
This will help you to clear badge if push come when app is being open. User seeing notification and you clear it, when he press Home Button (once or twice). Also it will be clear if app being closed (clear after user open it).
Here you can see when this method called.