27 марта 2024 Нет комментариев
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate{
    var webView: WKWebView!
    lazy var progressbar: UIProgressView = UIProgressView();
    deinit {
        self.webView.removeObserver(self, forKeyPath: "estimatedProgress")
        self.webView.scrollView.removeObserver(self, forKeyPath: "contentOffset")
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        let webConfiguration = WKWebViewConfiguration();
        webConfiguration.dataDetectorTypes = [.all]
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        webView.translatesAutoresizingMaskIntoConstraints = false
        self.webView.navigationDelegate = self
        view.addSubview(webView)
        self.webView.frame = self.view.frame
        self.webView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)
        ])
        self.webView.addSubview(self.progressbar)
        self.setProgressBarPosition()
        webView.scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
        self.progressbar.progress = 0.1
        self.progressbar.trackTintColor = .white
        self.progressbar.progressTintColor = UIColor(red:244/255.0, green: 66/255.0, blue: 8/255.0, alpha: 1)
        webView.addObserver(self, forKeyPath: "estimatedProgress",options: .new, context: nil)
        let myURL = URL(string:"https://ya.ru")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: #selector(reloadWebView(_:)), for: .valueChanged)
        webView.scrollView.addSubview(refreshControl)
        if #available(iOS 11.0, *){
            webView.scrollView.contentInsetAdjustmentBehavior = .never;
        }
        webView.navigationDelegate = self
        webView.allowsBackForwardNavigationGestures = true
    }
    func setProgressBarPosition(){
        self.progressbar.translatesAutoresizingMaskIntoConstraints = false
        self.webView.removeConstraints(self.webView.constraints)
        self.webView.addConstraints([
            self.progressbar.topAnchor.constraint(equalTo: self.webView.topAnchor, constant: self.webView.scrollView.contentOffset.y * -1),
            self.progressbar.leadingAnchor.constraint(equalTo: self.webView.leadingAnchor),
            self.progressbar.trailingAnchor.constraint(equalTo: self.webView.trailingAnchor)
        ])
    }
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        switch keyPath{
        case "estimatedProgress":
            if self.webView.estimatedProgress >= 1.0 {
                UIView.animate(withDuration: 0.3, animations: {() in
                    self.progressbar.alpha = 0.0
                }, completion: { finished in
                    self.progressbar.setProgress(0.0, animated: false)
                })
            } else{
                self.progressbar.isHidden = false
                self.progressbar.alpha = 1.0
                progressbar.setProgress(Float(self.webView.estimatedProgress), animated: true)
            }
        case "contentOffset":
            self.setProgressBarPosition()
        default:
            super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        }
    }
    @objc func reloadWebView(_ sender: UIRefreshControl){
        webView.reload()
        sender.endRefreshing()
    }
    func share(message: String, link: String){
        if let link = NSURL(string: link){
            let objectsToShare = [message, link] as [Any]
            let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
            self.present(activityVC, animated: true, completion: nil)
        }
    }
}
extension ViewController: WKNavigationDelegate{
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void){
        guard
            let url = navigationAction.request.url else{
            decisionHandler(.cancel)
            return
        }
        let string = url.absoluteString
        if(string.contains("mailto:")){
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)
            return
        }
        if(string.contains("tel:")){
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)
            return
        }
        if(string.contains("?share")){
            let urlArr = string.components(separatedBy: "?")
            let link = urlArr[0]
            share(message: "", link: link)
            decisionHandler(.cancel)
            return
        }
        decisionHandler(.allow)
    }
}

https://josh.blog/2020/02/swiftui-webview-with-a-progress-bar

Categories: Other Tags:
27 марта 2024 Нет комментариев
self.progressbar.trackTintColor = .white
self.progressbar.progressTintColor = UIColor(red:244/255.0, green: 66/255.0, blue: 8/255.0, alpha: 1)
Categories: iOS Tags:
27 марта 2024 Нет комментариев
func share(message: String, link: String){
	if let link = NSURL(string: link){
		let objectsToShare = [message, link] as [Any]
		let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
		self.present(activityVC, animated: true, completion: nil)
	}
}
share(message: "test", link: "https://ya.ru/")

https://stackoverflow.com/questions/37938722/how-to-implement-share-button-in-swift

Categories: iOS Tags:
27 марта 2024 Нет комментариев
if(string.contains("?share")){
	let urlArr = string.components(separatedBy: "?")
	let link = urlArr[0]
}
Categories: iOS Tags:
16 февраля 2024 Нет комментариев

Также в случае отсутствия gclid и utm определять источник по $_SERVER[‘HTTP_REFERER’] учитывая домены поисковых систем.

$seo_params=array('ga_cid','gclid','utm_source','utm_medium','utm_campaign','utm_content','utm_term');
$seo_cookies=$seo_cookies_default=array();
foreach($seo_params as $sp){
	switch($sp){
		case 'gclid':
			$seo_cookies_default[$sp]='NULL';
		break;
		case 'utm_source':
			$seo_cookies_default[$sp]='direct';
		break;
		default:
			$seo_cookies_default[$sp]='none';
		break;
	}
}
$update_cookies=false;
if(isset($_GET['gclid'])&&$_GET['gclid']!=''){
	$update_cookies=true;
	foreach($seo_params as $sp){
		switch($sp){
			case 'gclid':
				$seo_cookies[$sp]=$_GET[$sp];
			break;
			case 'utm_source':
				$seo_cookies[$sp]='google';
			break;
			case 'utm_medium':
				$seo_cookies[$sp]='cpc';
			break;
			default:
				if(stristr($sp,'utm_')&&isset($_GET[$sp])&&$_GET[$sp]!=''){
					$seo_cookies[$sp]=$_GET[$sp];
				}
				else{
					$seo_cookies[$sp]='none';
				}
			break;
		}
	}
}
else{
	$is_utm=false;
	foreach($seo_params as $sp){
		if(stristr($sp,'utm_')&&isset($_GET[$sp])&&$_GET[$sp]!=''){
			$seo_cookies[$sp]=$_GET[$sp];
			$is_utm=true;
			$update_cookies=true;
		}
		else{
			$seo_cookies[$sp]='none';
		}
	}
	if(!$is_utm){
		$referer=$_SERVER['HTTP_REFERER'];
		if($referer!=''){
			$parse_referer=parse_url($referer);
			$referer_domain=$parse_referer['host'];
			if($referer_domain!=''&&$referer_domain!=$_SERVER['HTTP_HOST']){
				$update_cookies=true;
				$organics=array('google','yandex','bing');
				$is_organic=false;
				foreach($organics as $organic){
					if(stristr($referer_domain,$organic)){
						$is_organic=true;
						foreach($seo_params as $sp){
							switch($sp){
								case 'utm_source':
									$seo_cookies[$sp]=$organic;
								break;
								case 'utm_medium':
									$seo_cookies[$sp]='organic';
								break;
								default:
									if(stristr($sp,'utm_')){
										$seo_cookies[$sp]='none';
									}
								break;
							}
						}
					}
				}
				if(!$is_organic){
					foreach($seo_params as $sp){
						switch($sp){
							case 'utm_source':
								$seo_cookies[$sp]=$referer_domain;
							break;
							case 'utm_medium':
								$seo_cookies[$sp]='referral';
							break;
							default:
								if(stristr($sp,'utm_')){
									$seo_cookies[$sp]='none';
								}
							break;
						}
					}
				}
			}
		}
	}
}
if($_COOKIE['_ga']!=''){
	$ga_cookie_split=explode('.',$_COOKIE['_ga']);
	if($ga_cookie_split[2]&&$ga_cookie_split[3]){
		$ga_cid=$ga_cookie_split[2].'.'.$ga_cookie_split[3];
		$seo_cookies['ga_cid']=$ga_cid;
	}
}
foreach($seo_params as $sp){
	if($update_cookies||!isset($_COOKIE['local_'.$sp])||$sp=='ga_cid'){
		$cv=($seo_cookies[$sp]!='')?$seo_cookies[$sp]:$seo_cookies_default[$sp];
		setcookie('local_'.$sp,$cv,time()+31536000,'/',$_SERVER['HTTP_HOST']);
		$_COOKIE['local_'.$sp]=$cv;
	}
}
function add_seo_params_to_letter(){
	global $seo_params;
	$text='<hr/>';
	foreach($seo_params as $sp){
		$text.=$sp.': '.$_COOKIE['local_'.$sp]."<br/>";
	}
	return $text;
}

Функция add_seo_params_to_letter используется для добавления в письма сохраненных данных.
Например в modx:

// /core/components/formit/model/formit/fihooks.class.php
public function email(array $fields=array()){
	// ...
	$message.=add_seo_params_to_letter();
	// ...
}
Categories: PHP Tags:
16 февраля 2024 Нет комментариев

Также в случае отсутствия gclid и utm определять источник по document.referrer учитывая домены поисковых систем.

document.addEventListener("DOMContentLoaded",function(event){
	var seo_params=new Array('ga_cid','gclid','utm_source','utm_medium','utm_campaign','utm_content','utm_term');
	var seo_cookies=new Array();
	var seo_cookies_default=new Array();
	var params=new URLSearchParams(location.search);
	seo_params.forEach((sp)=>{
		switch(sp){
			case 'gclid':
				seo_cookies_default[sp]='NULL';
			break;
			case 'utm_source':
				seo_cookies_default[sp]='direct';
			break;
			default:
				seo_cookies_default[sp]='none';
			break;
		}
	});
	var update_cookies=false;
	if(params.has('gclid')&&params.get('gclid')!=''&&params.get('gclid')!='none'){
		update_cookies=true;
		seo_params.forEach((sp)=>{
			switch(sp){
				case 'gclid':
					seo_cookies[sp]=params.get(sp);
				break;
				case 'utm_source':
					seo_cookies[sp]='google';
				break;
				case 'utm_medium':
					seo_cookies[sp]='cpc';
				break;
				default:
					if(sp.indexOf('utm_')!=-1&&params.has(sp)&&params.get(sp)!=''){
						seo_cookies[sp]=params.get(sp);
					}
					else{
						seo_cookies[sp]='none';
					}
				break;
			}
		});
	}
	else{
		var is_utm=false;
		seo_params.forEach((sp)=>{
			if(sp.indexOf('utm_')&&params.has(sp)&&params.get(sp)!=''){
				seo_cookies[sp]=params.get(sp);
				is_utm=true;
				update_cookies=true;
			}
			else{
				seo_cookies[sp]='none';
			}
		});
		if(!is_utm){
			var referer=document.referrer;
			if(referer!=''){
				var referer_domain=referer.split('/')[2];
				if(referer_domain!=''&&referer_domain!=location.hostname){
					update_cookies=true;
					var organics=new Array('google','yandex','ya.','bing');
					var is_organic=false;
					organics.forEach((organic)=>{
						if(referer_domain.indexOf(organic)!=-1){
							if(organic=='ya.'){
								organic='yandex'
							}
							is_organic=true;
							seo_params.forEach((sp)=>{
								switch(sp){
									case 'utm_source':
										seo_cookies[sp]=organic;
									break;
									case 'utm_medium':
										seo_cookies[sp]='organic';
									break;
									default:
										if(sp.indexOf('utm_')){
											seo_cookies[sp]='none';
										}
									break;
								}
							});
						}
					});
					if(!is_organic){
						seo_params.forEach((sp)=>{
							switch(sp){
								case 'utm_source':
									seo_cookies[sp]=referer_domain;
								break;
								case 'utm_medium':
									seo_cookies[sp]='referral';
								break;
								default:
									if(sp.indexOf('utm_')!=-1){
										seo_cookies[sp]='none';
									}
								break;
							}
						});
					}
				}
			}
		}
	}
	var ga_cookie=document.cookie.match(new RegExp('(^| )_ga=([^;]+)'));
	if(ga_cookie[2]){
		var ga_cookie_split=ga_cookie[2].split(".");
		var ga_cid=ga_cookie_split[2]+'.'+ga_cookie_split[3];
		seo_cookies['ga_cid']=ga_cid;
	}
	seo_params.forEach((sp)=>{
		var sp_cookie=document.cookie.match(new RegExp('(^| )local_'+sp+'=([^;]+)'));
		if(update_cookies||!sp_cookie||sp=='ga_cid'){
			var cv=(seo_cookies[sp]!='')?seo_cookies[sp]:seo_cookies_default[sp];
			document.cookie=encodeURIComponent('local_'+sp)+'='+encodeURIComponent(cv);
		}
	});
	var links=document.getElementsByTagName("a");
	for(i=0;i<links.length;i++){
		var href=links[i].href;
		if(href.includes(document.domain)&&!(href.includes('#'))){
			seo_params.forEach((sp)=>{
				var sp_cookie=document.cookie.match(new RegExp('(^| )local_'+sp+'=([^;]+)'));
				if(sp_cookie[2]){
					href+=(href.includes('?'))?"&":"?";
					href+=sp+"="+sp_cookie[2];
				}
			})
			links[i].href=href;
		}
	}
	const url=new URL(window.location.href);
	seo_params.forEach((sp)=>{
		var sp_cookie=document.cookie.match(new RegExp('(^| )local_'+sp+'=([^;]+)'));
		if(sp_cookie[2]&&!params.has(sp)){
			url.searchParams.append(sp,sp_cookie[2]);
		}
	});
	window.history.pushState(null,null,url);
});
Categories: Javascript Tags:
1 февраля 2024 Нет комментариев

ios webview pull to refresh

override func viewDidLoad() {
	// after webView.load
	let refreshControl = UIRefreshControl()
	refreshControl.addTarget(self, action: #selector(reloadWebView(_:)), for: .valueChanged)
	webView.scrollView.addSubview(refreshControl)
}
@objc func reloadWebView(_ sender: UIRefreshControl){
	webView.reload()
	sender.endRefreshing()
}
Categories: iOS Tags: