iOS15 Webview using `Video` causes crashes - `WebAVPlayerController valueForUndefinedKey - playingOnMatchPointDevice ` - crash

iOS15 Webview's HTML using Video tag, the following crash occurs, does anyone know what is the reason for this?
[<WebAVPlayerController 0x282f41420> valueForUndefinedKey:]: this class is not key value coding-compliant for the key playingOnMatchPointDevice.

In default configuration the WKWebView loads the page, and the internal video playback can only be played after the user's active operation, and it must be played in full screen. This configuration may not meet the business needs, and the web video should be played inline and automatically in the page. So you should set WKWebViewConfiguration, the specific code is as follows:
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.allowsInlineMediaPlayback = YES;
if (#available(iOS 10.0, *)) {
configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
} else {
configuration.requiresUserActionForMediaPlayback = NO;
}
And your web page needs to set video too, for example
<video width="320" height="240" controls="" webkit-playsinline="true" playsinline="true">
<source src="https://xx.com.xxx.mp4" type="video/mp4">
</video>

I have solved the same problem, there is a [IM open source SDK-MobileimSDK4i] in the project, and it will be good after deleting it, the specific problem of the subsequent block is unknown!

Related

Why are images in react-native app not rendering after Xcode 12 update

Not sure what to even document here. I update Xcode to 12.0.1, and out of nowhere, after building and running my application, the images inside the app are not rendering, not counting the splash screen, containing an image, which are built out natively.
These images, whether they're coming from firebase storage (remotely) or whether they're icons (locally) are simply not rendering. no changes in any image code or anything, anywhere in the application. the only change was the Xcode 12 update. and also a macOS update to Catalina 10.15.7
Any ideas on whats going on? let me know If I can provide additional details.
This behavior is a known issue with iOS 14 as you can see here.
You need to change the following file:
react-native/Libraries/Image/RCTUIImageViewAnimated.m
and add the following line:
- (void)displayLayer:(CALayer *)layer
{
if (_currentFrame) {
layer.contentsScale = self.animatedImageScale;
layer.contents = (__bridge id)_currentFrame.CGImage;
} else {
[super displayLayer:layer]; // add else statement with this line here
}
}
Source: https://github.com/facebook/react-native/issues/29279#issuecomment-658244428

iOS: How can I find one specific tag in a HTML page

I am parsing a website and want to read out one specific HTML part of that website. I am looking for one (and one only) <frame> tag:
<frame scrolling="auto" ... src=”I need this text">
So I need basically only the text in src="". But how can I do this as simple as possible? So far I tried to analyze the string by:
NSString *html = [self.webview stringByEvaluatingJavaScriptFromString: #"document.body.innerHTML"];
But html stays empty and I wouldn't know how to continue. So how can I make this as simple as possible using my webview?
Something like this might work:
document.addEventListener("DOMContentLoaded", function() {
var allFrames = document.querySelectorAll("frame");
if (allFrames.length) {
var src = allFrames[0].src;
console.log(src);
var request = new XMLHttpRequest();
request.open("GET", "my-app://localhost/?src=" + encodeURIComponent(src));
request.send(null);
} else {
console.log("no frames on the page " + location.href);
}
});
Run this code using stringByEvaluatingJavaScriptFromString from the webViewDidFinishLoad callback, and handle the output data from the script using shouldStartLoadWithRequest callback.
You see the log and debug the script using Safari Web Inspector (for both simulator and device).

Can I preload the web content for Safari View Controller?

I can create Safari View Controller without problem:
let svc = SFSafariViewController(URL: NSURL(string: remote_url)!, entersReaderIfAvailable: true)
self.presentViewController(svc, animated: true, completion: nil)
Is there any way I can preload the URL before I present the view controller to the user?
For example, I can preload the URL (web content) in the background first, and after the user clicks on something, I can show the Safari View Controller with the content right away. The user will feel the page loading is faster or instant.
P.S. Workarounds/hacks are also acceptable. For example, using cache or starting the view controller in background, etc.
EDIT: please consider SFSafariViewController only.
Here is a solution.
Obviously, if you click on the button right away you'll see the loading.
But basically, I load the Browser and put the view behind another one and I put a button in this other view.
When you press the button, the browser is bring to the front, already loaded.
The only problem here is that I'm not using any transition but that's one solution at least.
import UIKit
import SafariServices
class ViewController: UIViewController {
var svc = SFSafariViewController(URL: NSURL(string: "https://microsoft.com/")!, entersReaderIfAvailable: true)
var safariView:UIView?
let containerView = UIView()
let btn = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
//let tmpView = svc.view
addChildViewController(svc)
svc.didMoveToParentViewController(self)
svc.view.frame = view.frame
containerView.frame = view.frame
containerView.backgroundColor = UIColor.redColor()
safariView = svc.view
view.addSubview(safariView!)
view.addSubview(containerView)
btn.setTitle("Webizer", forState: UIControlState.Normal)
btn.titleLabel!.textColor = UIColor.blackColor()
btn.addTarget(self, action: "buttonTouched:", forControlEvents: .TouchUpInside)
btn.frame = CGRectMake(20, 50, 100, 100)
containerView.addSubview(btn)
view.sendSubviewToBack(safariView!)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func buttonTouched(sender: AnyObject) {
view.bringSubviewToFront(safariView!)
//self.presentViewController(svc, animated: true, completion: nil)
}
}
Sadly this behaviour is not supported with the current implementation of SFSafariViewController. I would encourage filing a radar with Apple to add support for this behaviour but like others have suggested your best bet is to use WKWebView and start loading before its added to the hierarchy.
I came across a lovely radar from Twitter that actually mentions exactly what you're asking for. I think you might find the following requests useful:
High Priority:
- Ability to warm the SFSafariViewController before actually presenting it with a URL, URL request, HTML data or file on disk
- Currently, are investing heavily into warming the shared URL cache for high priority Tweets so that if the user hits that Tweet we
will open UIWebView (sadly not WKWebView) with that pre-cached web
page. If we could just warm an SFSafariViewController with the
desired link, this would eliminate an enormous amount of effort on our
end.
You can see in their implementation they simply cache responses using UIWebView since WKWebView seems to obfuscate the caching semantics a bit. The only risk is that UIWebView is a likely candidate for deprecation as you see in their docs "In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView."
So unfortunately it seems that their are many hoops you need to jump through to get this all going so your best bet for now is to just pester Apple and dupe Twitters radar.
You could try using a http cache, but I don't think it would work as the Safari View Controller is working as a separate process (probably the same as Safari), so that's why it e.g. circumvents ATS.
The only way I can think of this working is to somehow force the user's Safari to load it? openURL: or adding to Reading List maybe? This doesn't sound like a viable solution.
You can always experiment with custom presentation of the view controller, attach it the view hierarchy, trigger appearance events, but set its frame to CGRectMake(0,0,1,1) or attach it somewhere off-screen, then wait a while and represent it with a correct frame.
you can download the web page using the following code . and represent it with the help of svc
let data:NSData?
do {
let weatherData = try NSData(contentsOfURL: NSURL(string: remote_url)!, options: NSDataReadingOptions())
data = weatherData
print(weatherData)
} catch {
print(error)
}
and load it when you needed in the svc
While it's technically possible to use the solution above to achieve what you're asking, this may not pass App Store review. Per the SFSafariViewController docs:
In accordance with App Store Review Guidelines, this view controller must be used to visibly present information to users; the controller may not be hidden or obscured by other views or layers. Additionally, an app may not use SFSafariViewController to track users without their knowledge and consent.

Retina Images not being loaded on sencha touch

I've included retina.js in my Sencha Touch application. When watching the network monitor I see
retina.js is loaded
images are loaded normaly example.jpg
no #2x images are loaded example#2x.jpg or even looked for
Using chrome to emulate an iphone this is all I see
I also manually ran Retina.init(window) however nothing happens. All images remain non-retina. Running Retina.isRetina() returns true
I don't actually own a retina device, so I am not sure if that is the issue. However my friend with an iPhone 5s says the image quality has not improved, so I am assuming the retina images are not showing up.
The documentation is not very helpful
I figure this has to do with the fact that images are created and loaded with JS (the images are not there onload)
Using chrome for debugging, how can I make retina.js work for my app?
OK, so I used a small part of the retina.js file and created a new class, it uses the isRetina function to tell weather the devicePixelRatio is higher than 1.
Ext.define('MyApp.Retina', {
singleton: true,
isRetina : function(){
var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
(min--moz-device-pixel-ratio: 1.5),\
(-o-min-device-pixel-ratio: 3/2),\
(min-resolution: 1.5dppx)";
if (window.devicePixelRatio > 1)
return true;
if (window.matchMedia && window.matchMedia(mediaQuery).matches)
return true;
return false;
},
getSrc: function(url){
return this.isRetina()? [url.slice(0, -4), '#2x', url.slice(-4)].join(''): url;
}
});
Now throughout my sencha app I create images with MyApp.Retina.('http://example.com/foo.jpg') as src value, when the device is retina the function returns http://example.com/foo#2x.jpg

Getting Safari document title/location with Scripting Bridge does not work in full-screen mode

I'm trying to get the URL and document title from the topmost Safari document/tab. I have an AppleScript and an objective-c version using Apple's Scripting Bridge framework.
Both versions work fine for most web pages, however when I open a Youtube video in full-screen mode, the Scripting Bridge based version fails. The Apple Script works fine for "normal" and full-screen Safari windows.
Can anyone see what is wrong with the Scripting Bridge code below to cause it to fail for full-screen Safari windows?
Here the code (I omitted error checking for brevity):
AppleScript:
tell application "Safari"
# Give us some time to open video in full-screen mode
delay 10
do JavaScript "document.title" in document 0
end tell
Scripting Bridge:
SafariApplication* safari = [SBApplication applicationWithBundleIdentifier:#"com.apple.Safari"];
SBElementArray* windows = [safari windows];
SafariTab* currentTab = [[windows objectAtIndex: 0] currentTab];
// This fails when in full-screen mode:
id result = [safari doJavaScript: #"document.title" in: currentTab];
NSLog(#"title: %#", result);
Scripting Bridge error (with added line breaks):
Apple event returned an error. Event = 'sfri'\'dojs'{
'----':'utxt'("document.title"),
'dcnm':'obj '{ 'want':'prop',
'from':'obj '{ 'want':'cwin',
'from':'null'(),
'form':'indx',
'seld':1 },
'form':'prop',
'seld':'cTab' }
}
Error info = {
ErrorNumber = -1728;
ErrorOffendingObject = <SBObject #0x175c2de0:
currentTab of SafariWindow 0 of application "Safari" (238)>;
}
I could not find details about the given error code. It complains about 'currentTab' which shows that the JavaScript event at least made it all the way to Safari. I assume that the current tab receives the event, but refuses to run the JS code, because it is in full-screen mode. However, why does this work for an AppleScript? Don't they use the same code path eventually?
Any suggestions are greatly appreciated. Thanks!
This appears to be a failure in the header file created by sdef/sdp--your Objective-C does not parallel your working AppleScript (and the header file seemed to indicate that there is no doJavaScript:in: that would work on a document, as in your AppleScript). When I used the following code, which does parallel your AppleScript, it gave the title without error even for a full-screen YouTube video. The cast from SafariDocument* to SafariTab* in order to use doJavaScript:in: feels wrong, but seems to work.
SafariApplication* safari = [SBApplication applicationWithBundleIdentifier:#"com.apple.Safari"];
SBElementArray* documents = [safari documents];
SafariDocument* frontDocument = [documents objectAtIndex: 0];
// This *no longer* fails when in full-screen mode:
id result = [safari doJavaScript: #"document.title" in: (SafariTab *) frontDocument];
NSLog(#"title: %#", result);
tell application "Safari"
get URL of current tab of front window
end tell
The Objective-C is then simply
SafariApplication* safari = [SBApplication
applicationWithBundleIdentifier:#"com.apple.Safari"];
for (SafariWindow *window in safari.windows) {
if ([window visible]) {
result = window.currentTab.URL;
break;
}
}