iOS - detect when user copy to clipboard - [UIPasteboard generalPasteboard] - iphone

quick easy question
while using a WebView with some text in it - the user can select a snippet of text from it
and press a UIButton which I created - running the following action:
-(IBAction)copyToClip
{
NSString *copyClip = [UIPasteboard generalPasteboard].string;
NSLog(#"Clip = %#",copyClip);
// (works fine)
}
I would like to call the same function without a UIButton, thus when the user did a "copy" action it will activate the above code. (I assume a listener)
what would be the appropriate listener for this?

Use NSNotificationCenter and register for UIPasteboardChangedNotification:
http://developer.apple.com/library/IOs/documentation/UIKit/Reference/UIPasteboard_Class/Reference.html#//apple_ref/c/data/UIPasteboardChangedNotification
[[NSNotificationCenter defaultCenter] addObserver:object selector:#selector(copyToClip) name:UIPasteboardChangedNotification object:nil];

If someone is interested in the Xamarin/C# version:
NSNotificationCenter.DefaultCenter.AddObserver(UIPasteboard.ChangedNotification,
notification => {
// custom code here
});

Related

can we hide the native keyboard of ipad device on focus on textfield

I am working on phone Gap application in which i am using my custom jquery keyboard but when i focus on the input the native keyboard of device is open. I did't have knowledge of objective-C so please can u help me to prevent the native keyboard on ios device when i click on the text field.
I am trying to do but it's work only for one time when i double click on the input field the application is crashed.
my code is..
// register for keyboard show event
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
// hiding UIWebviewAccessary
// http://ios-blog.co.uk/iphone-development-tutorials/rich-text-editing-a-simple-start-part-1/
- (void)keyboardWillShow:(NSNotification *)note {
[self.view endEditing:YES];
[self removeBar];
[self performSelector:#selector(adjustFrame) withObject:nil afterDelay:0.03];
}
- (void)adjustFrame {
[self.webView stringByEvaluatingJavaScriptFromString:#"window.scroll(0,0)"];
}
You can use below
// automatically close the keyboard on iOS
document.activeElement.blur();
But i thinks u want to close keyboard when your input Focus().
also use ..
var hideKeyboard = function() {
document.activeElement.blur();
$("input").blur();
};

Get Notification when a video starts or stops in UIWebView

Hello i am new to objective - c
I'm having a problem with the UIWebView and MPMoviePlayerController: My UIWebView has a movie inside the html (it's a local html file), I'm using html5 and a video tag for the video.
I want a notification when video starts or stops in UIWebView....
I have tried using MPMoviePlayerPlaybackDidFinishNotification, but it doesnt fire ...
I have also tried to make the my main UIViewController's view a view of my own, and intercept -didAddSubview: and -willRemoveSubview:. but with no sucess...
Does any body know how to get notification from uiwebview??
You can observe #"MPAVControllerPlaybackStateChangedNotification" (use nil for the object). This notification isn't documented so I don't know if the App Store will approve your app.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playbackStateDidChange:)
name:#"MPAVControllerPlaybackStateChangedNotification"
object:nil];
The notification has the key MPAVControllerNewStateParameter in its userInfo. The value seems to be 0 before playback starts, 1 when it is paused, 2 when it is playing, and 3 (momentarily) when you are dragging the playback slider.
- (void)playbackStateDidChange:(NSNotification *)note
{
NSLog(#"note.name=%# state=%d", note.name, [[note.userInfo objectForKey:#"MPAVControllerNewStateParameter"] intValue]);
}
I searched alot about this..Here is the solution that I have found for getting the playback end notification call. Tested code on iOS6.0 and above. All thanks to #Morten.
In viewDidLoad add observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playbackDidEnd:)
name:#"MPAVControllerItemPlaybackDidEndNotification"//#"MPAVControllerPlaybackStateChangedNotification"
object:nil];
Then simply add following javascript code webViewDidFinishLoad delegate as below
- (void)webViewDidFinishLoad:(UIWebView *)webView {
//http://stackoverflow.com/a/12504918/860488
[videoView stringByEvaluatingJavaScriptFromString:#"\
var intervalId = setInterval(function() { \
var vph5 = document.getElementById(\"video-player\");\
if (vph5) {\
vph5.playVideo();\
clearInterval(intervalId);\
} \
}, 100);"];
}
- (void)playbackDidEnd:(NSNotification *)note
{
//do your stuff here
[videoView removeFromSuperview];
videoView.delegate = nil;
videoView = nil;
}
You will get playbackDid End call in the above selected and can do whatever is your requirement.
Happy Coding !!

Unhiding a view is very slow in CTCallCenter callEventHandler

Reposting with more concise and focused question after original question went unanswered. Also adding more insight into the problem after another day of research:
In my app delegate (didFinishLaunching), I set up a callEventHandler on CTCallCenter.
The idea is that when a callState changes, I post a notification with a userInfo dict
containing the call.callState. In my view, I observe this notification, and when the
userInfo dict contains a value of CTCallDisconnected, I want to unhide a view.
The problem I'm having is that the unhiding aspect is taking, almost consistenly, ~ 7 seconds.
Everything else is working fine, and I know this because I NSLog before and after the unhiding,
and those logs appear immediately, but the darned view still lags for 7 seconds.
Here's my code:
appDidFinishLaunching:
self.callCenter = [[CTCallCenter alloc] init];
self.callCenter.callEventHandler = ^(CTCall* call) {
// anounce that we've had a state change in our call center
NSDictionary *dict = [NSDictionary dictionaryWithObject:call.callState forKey:#"callState"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"CTCallStateDidChange" object:self userInfo:dict];
};
I then listen for this notification when a user taps a button that dials a phone number:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ctCallStateDidChange:) name:#"CTCallStateDidChange" object:nil];
Then, in ctCallStateDidChange:
- (void)ctCallStateDidChange:(NSNotification *)notification
{
NSLog(#"121");
NSString *callInfo = [[notification userInfo] objectForKey:#"callState"];
if ([callInfo isEqualToString:CTCallStateDisconnected]) {
NSLog(#"before show");
[self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
NSLog(#"after show");
}
}
I've tracked the problem down to the if condition in the above code sample:
if ([[userInfo valueForKey:#"userInfo"] valueForKey:#"callState"] == CTCallStateDisconnected) {
If I simply replace that with:
if (1 == 1) {
Then the view appears immediately!
The thing is, those NSLog statements are logging immediately, but the view is
lagging in it's unhiding. How could that condition cause only part of it's block
to execute immediately, and the rest to wait ~ 7 seconds?
Thanks!
Try changing your code to this:
- (void)ctCallStateDidChange:(NSNotification *)notification
{
NSLog(#"121");
NSString *callInfo = [[notification userInfo] objectForKey:#"callState"];
if ([callInfo isEqualToString:CTCallStateDisconnected]) {
NSLog(#"before show");
[self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
NSLog(#"after show");
}
}
Note:
The parameter is an NSNotification, not an NSDictionary
I would not compare strings with ==
No need to cast the view to change the hidden property
Use NO instead of false
Update: Got an idea: Could you try the following, please, in between the NSLogs?
dispatch_async(dispatch_get_main_queue(), ^{
[self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
});
Reading the CTCallCenter doc, it seems the callEventHandler is dispatched on "the default priority global dispatch queue", which is not the main queue where all the UI stuff happens.
Looks like there is no problem with your hidden code. If I were you, I would comment out all the code after the call ends, and uncomment them one by one to see what is the problem.
Hm... try to call [yourViewController.view setNeedsDisplay] after you change hidden property. Or avoid hidden, use alpha or addSubview: and removeFromSuperview methods instead.
djibouti33,
Where you put this sentence to listen when a user taps a button that dials a phone number?on WillResignActive function?
this sentence --> [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ctCallStateDidChange:) name:#"CTCallStateDidChange" object:nil];
Thanks for your time,
Willy.

Specific expression in if condition causes 7 second delay in execution [duplicate]

Reposting with more concise and focused question after original question went unanswered. Also adding more insight into the problem after another day of research:
In my app delegate (didFinishLaunching), I set up a callEventHandler on CTCallCenter.
The idea is that when a callState changes, I post a notification with a userInfo dict
containing the call.callState. In my view, I observe this notification, and when the
userInfo dict contains a value of CTCallDisconnected, I want to unhide a view.
The problem I'm having is that the unhiding aspect is taking, almost consistenly, ~ 7 seconds.
Everything else is working fine, and I know this because I NSLog before and after the unhiding,
and those logs appear immediately, but the darned view still lags for 7 seconds.
Here's my code:
appDidFinishLaunching:
self.callCenter = [[CTCallCenter alloc] init];
self.callCenter.callEventHandler = ^(CTCall* call) {
// anounce that we've had a state change in our call center
NSDictionary *dict = [NSDictionary dictionaryWithObject:call.callState forKey:#"callState"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"CTCallStateDidChange" object:self userInfo:dict];
};
I then listen for this notification when a user taps a button that dials a phone number:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ctCallStateDidChange:) name:#"CTCallStateDidChange" object:nil];
Then, in ctCallStateDidChange:
- (void)ctCallStateDidChange:(NSNotification *)notification
{
NSLog(#"121");
NSString *callInfo = [[notification userInfo] objectForKey:#"callState"];
if ([callInfo isEqualToString:CTCallStateDisconnected]) {
NSLog(#"before show");
[self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
NSLog(#"after show");
}
}
I've tracked the problem down to the if condition in the above code sample:
if ([[userInfo valueForKey:#"userInfo"] valueForKey:#"callState"] == CTCallStateDisconnected) {
If I simply replace that with:
if (1 == 1) {
Then the view appears immediately!
The thing is, those NSLog statements are logging immediately, but the view is
lagging in it's unhiding. How could that condition cause only part of it's block
to execute immediately, and the rest to wait ~ 7 seconds?
Thanks!
Try changing your code to this:
- (void)ctCallStateDidChange:(NSNotification *)notification
{
NSLog(#"121");
NSString *callInfo = [[notification userInfo] objectForKey:#"callState"];
if ([callInfo isEqualToString:CTCallStateDisconnected]) {
NSLog(#"before show");
[self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
NSLog(#"after show");
}
}
Note:
The parameter is an NSNotification, not an NSDictionary
I would not compare strings with ==
No need to cast the view to change the hidden property
Use NO instead of false
Update: Got an idea: Could you try the following, please, in between the NSLogs?
dispatch_async(dispatch_get_main_queue(), ^{
[self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO;
});
Reading the CTCallCenter doc, it seems the callEventHandler is dispatched on "the default priority global dispatch queue", which is not the main queue where all the UI stuff happens.
Looks like there is no problem with your hidden code. If I were you, I would comment out all the code after the call ends, and uncomment them one by one to see what is the problem.
Hm... try to call [yourViewController.view setNeedsDisplay] after you change hidden property. Or avoid hidden, use alpha or addSubview: and removeFromSuperview methods instead.
djibouti33,
Where you put this sentence to listen when a user taps a button that dials a phone number?on WillResignActive function?
this sentence --> [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(ctCallStateDidChange:) name:#"CTCallStateDidChange" object:nil];
Thanks for your time,
Willy.

Grabbing the UIPasteboard like Pastebot while running in the background

I know this is possible as Tapbots Pastebot does this. I am trying to grab the UIPasteboard when my iPhone app is running in the background and add it to a UITableView just as Pastebot does but I am also trying to shorten the link, if its a URL and copy that back to the UIPastboard so its ready for the user to paste anywhere. Now Pastebot apparently runs in the background by playing an audio file for 10 minutes. I have set up the NSNotificationCenter like so in the applicationDidFinishLaunching
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(pasteboardChangedNotification:) name:UIPasteboardChangedNotification object:[UIPasteboard generalPasteboard]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(pasteboardChangedNotification:) name:UIPasteboardRemovedNotification object:[UIPasteboard generalPasteboard]];
- (void)pasteboardChangedNotification:(NSNotification*)notification {
pasteboardChangeCount_ = [UIPasteboard generalPasteboard].changeCount;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if (pasteboardChangeCount_ != [UIPasteboard generalPasteboard].changeCount) {
[[NSNotificationCenter defaultCenter] postNotificationName:UIPasteboardChangedNotification object:[UIPasteboard generalPasteboard]];
}
}
Can anyone point me in a direction on grabbing the UIPasteboard and shortening a link, if its a URL and sending it back to the UIPasteboard? I have read the multitasking dev documents and the UIPasteboard documents. If anyone has a solution can you please share them with me?
Thanks
The only way I have managed to achieve something similar is by not bothering with the NSNotificationCenter and instead just copying the contents of the UIPasteboard at regular intervals whilst in the background.
The code bellow checks the UIPasteboard once a second for a thousand seconds. I believe that an application can run in the background for around 10 minutes without playing audio. If you play an audio file in the background the application can keep running.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Create a background task identifier
__block UIBackgroundTaskIdentifier task;
task = [application beginBackgroundTaskWithExpirationHandler:^{
NSLog(#"System terminated background task early");
[application endBackgroundTask:task];
}];
// If the system refuses to allow the task return
if (task == UIBackgroundTaskInvalid)
{
NSLog(#"System refuses to allow background task");
return;
}
// Do the task
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSString *pastboardContents = nil;
for (int i = 0; i < 1000; i++)
{
if (![pastboardContents isEqualToString:[UIPasteboard generalPasteboard].string])
{
pastboardContents = [UIPasteboard generalPasteboard].string;
NSLog(#"Pasteboard Contents: %#", pastboardContents);
}
// Wait some time before going to the beginning of the loop
[NSThread sleepForTimeInterval:1];
}
// End the task
[application endBackgroundTask:task];
});
}
Tapbots actually wrote an entry on their blog a few months back about the trick they use to get at the clipboard in the background. I don't use the app myself, so I can't verify that this ever came to fruition, but here's the relevant blog entry.
I know this is kind of an old thread. But I'd like to share this with you:
http://blog.daanraman.com/coding/monitor-the-ios-pasteboard-while-running-in-the-background/#comment-15135
However, I have my doubts whether Apple will reject this when trying to submit it to the App Store, as it feels to me like a hack. A hack that Apple tries hard to avoid with its whole background multitasking thing.
Anyone thoughts about it?