Create a unique identifer in a webview - ios

Go easy on me I am new to I OS and Swift :). I am trying to create a IOS app using swift. I have a web view display that is working correctly, displaying the website. YAY!!
What I need to do now is create a unique identifier that is stored locally and when the app is opened is sent to the remote server. I see i can use this...
UIDevice.currentDevice().identifierForVendor!.UUIDString
However i would like to store it locally for future use and send it to the remote server every time the app is opened. I have done research on this and have come upon answers for other objects just not a web view.
If someone knows of a tutorial or example code for this solution i would greatly appreciate it.
UPDATE
let uuid = UIDevice.currentDevice().identifierForVendor!.UUIDString
and for the url im using
let url= NSURL (string:"https://example.com");
Could i do something like this? Or like it?
let url= NSURL (string:"https://example.com");
let requestobj= NSURLRequest(URL:url! ADD VAR HERE? );
Where ADD VAR HERE is the uuid to pass to the server which i can catch with a php script?
Latest update..
Im having a hard time integrating that into my existing code. Where would be the best place to put it?
import UIKit
class ViewController: UIViewController {
let uuid = UIDevice.currentDevice().identifierForVendor!.UUIDString
#IBOutlet weak var WebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = NSURL (string: "https://example.com");
let requestObj = NSURLRequest(URL: url?)
WebView.loadRequest(requestObj);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Here is the answer i was looking for. Thanks for your help everyone!
let device_uuid = UIDevice.currentDevice().identifierForVendor!.UUIDString
let api_host = "https://example.com?uuid=" + device_uuid
let url = NSURL(string: api_host)
let req = NSURLRequest(URL: url!)
WebView.loadRequest(req);
Apparently what i needed to do was build my URL into a variable. Then i can structure it using the NSURL and use it from there. This guide helped me. Just ignore the ruby on rails part if that's not what your doing.
http://ericlondon.com/2015/12/09/sending-messages-between-a-swift-webview-and-a-rails-backend-using-javascript.html

You will need to check on the webserver side to confirm exactly what you need to pass in - but if you are developing that side as well, then you should have control :-)
Should be something like this - please not that you don't need ; in swift
let request= NSURLRequest(URL:url)
var bodyData = "myUUID=\(uuid)&otherData=value1"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);

Keep in mind that this identifier will change if a user uninstalls the application. If you need to persist it then I'd recommend to store it on the keychain so the id is always the same for the same phone even if the app is uninstalled.
Check this other question: How to preserve identifierForVendor in ios after uninstalling ios app on device?

Related

iOS swift extracting permalink from deeplink URL

I am implementing Firebase dynamic links in my iOS project. It is working fine and it is opening my iOS Home screen properly. But now I would like to extract values from url and open appropriate screen based on url.
for example:
https://www.dd.com/forums/hot-deals-online/topics/smart-tv-carniva
in this url I would like to get 'hot-deals-online' and 'smart-tv-carniva' permalink which I will pass to view controller to open that screen on the app
can someone suggest me best approach for this.
Shortest is to access path of URLComponents object:
let url = "https://www.dd.com/forums/hot-deals-online/topics/smart-tv-carniva"
if let comps = URLComponents(string: url) {
var elements = comps.path.split(separator: "/").map(String.init)
// ["forums", "hot-deals-online", "topics", "smart-tv-carniva"]
// To build an url back, example:
var url = URL(string: comps.host!)!
url.appendPathComponent(elements[0])
url.appendPathComponent(elements[1])
// Result: www.dd.com/forums/hot-deals-online
}
P.S. calling .map(String.init) makes in-place conversion from array of substrings to normal String array.

Synchronizing Apple Watch and iPhone using Swift 3 and Realm

I need to Display and modify my data structure from both Apple Watch and iPhone.
The Database:
I am currently using a simple Realm Structure where I have an Object A and an Object B which can hold lots of A's.
So on iPhone the user can create a B and add A's and view of course all A's and B's.
I want the Apple watch to show all A's of the current B and give the users the chance to add new A's to their current B.
The way I have tried to do it:
I wanted to move the hole Realm file from iPhone to the watch or the other way. (That was a tip from the Internet)
iPhone Code:
override func viewDidLoad() {
super.viewDidLoad()
if WCSession.isSupported() { //makes sure it's not an iPad or iPod
let watchSession = WCSession.default()
watchSession.delegate = self
watchSession.activate()
transferRealmFile()
if watchSession.isWatchAppInstalled {
do {
try watchSession.updateApplicationContext(["foo": "bar"])
} catch let error as NSError {
print(error.description)
}
}
}
}
func transferRealmFile(){
if let path = Realm.Configuration().fileURL {
WCSession.default().transferFile(path, metadata: nil)
}
}
WathcKit Extension:
func session(_ session: WCSession, didReceive file: WCSessionFile) {
//set the recieved file to default Realm file
var config = Realm.Configuration()
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
let realmURL = documentsDirectory.appendingPathComponent("data.realm")
if FileManager.default.fileExists(atPath: realmURL.path){
try! FileManager.default.removeItem(at: realmURL)
}
try! FileManager.default.copyItem(at: file.fileURL, to: realmURL)
config.fileURL = realmURL
Realm.Configuration.defaultConfiguration = config
}
Then I call transferRealmFile() every time I write to Realm. This works but I can't solve this Problems:
Problems:
It doesn't work if only watchKit App is started.
Apple Watch to iPhone doesn't work the same way. (I think I need to change the didRecived code, but I don't know what)
Question:
Do you know who to solve this 2 Problems or do you maybe know a better way to handle the situation or will the way we interact between iPhone an Watch change in WathcOS 3?
With watchOS1 it was possible to use AppGroups to share resources (even your Realm database) between an iOS app and its Watch extension. However, Apple removed this in watchOS 2, so now the only way to share data between your iOS and watchOS apps is via WatchConnectivity. Have a look at this answer.
Sadly the WatchConnectivity framework requires the WCSession to be active on both devices for transferring data, so you can't really get around problem 1.
In my opinion it is a better solution to only communicate the changes between the two apps and not send the whole Realm file, since your Realm file can get quite big and hence sending it forward and backward can take a lot of time and resources, while just sending the changes should be way faster.

URL, NSURL - compiler errors in code from the standard samples

m.b. I'm asking stupid question, but I'm really newbie in Swift and iPhone programming. Using XCode 8.0.
I want to create WebView application and have taken next code from here: https://sourcefreeze.com/uiwebview-example-using-swift-in-ios/
My Code :
import UIKit
import Foundation
class ViewController: UIViewController {
#IBOutlet weak var myWebView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = NSURL (string: "http://www.sourcefreeze.com");
let requestObj = NSURLRequest(URL: url!);
myWebView.loadRequest(requestObj);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Of course I've created UI object of UIWebView and connected it to controller:
#IBOutlet weak var myWebView: UIWebView!
During the build I receive next red alert:
'NSURL' is not implicitly convertible to 'URL'; did you mean to use 'as' to explicitly convert?
As I understand this code worked perfectly before 2 years. I guess that I'm missing something, but what?
Thanks for advance.
Try to use URL instead of NSURL as it is replaced with URL type in Swift 3
let url = URL(string: "http://www.sourcefreeze.com")
Here is the instruction from apple developer forum
The Swift overlay to the Foundation framework provides the URL
structure, which bridges to the NSURL class. The URL value type offers
the same functionality as the NSURL reference type, and the two can be
used interchangeably in Swift code that interacts with Objective-C
APIs. This behavior is similar to how Swift bridges standard string,
numeric, and collection types to their corresponding Foundation
classes.
For more information about value types, see Classes and Structures in
The Swift Programming Language (Swift 3) and Working with Cocoa
Frameworks in Using Swift with Cocoa and Objective-C (Swift 3).
It is the simplest way to solve issue:
let url = URL(string: "http://www.sourcefreeze.com")!
myWebView.load(URLRequest(url: url))
Xcode often tales you what is wrong. So from Xcode message it is possible to understand that NSURL should be converted to URL. Try to read relevant resources and bot use old tutorials. Swift is dynamically changes language always try to use up to date resources.
Try in this way
myWebView.loadRequest(NSURLRequest(URL: NSURL(string: "http://www.sourcefreeze.com")))
myWebView.delegate = self;
self.view.addSubview(myWebView)
This code worked:
let myUrl = URL (string: "http://www.sourcefreeze.com")!
let request = URLRequest(url: myUrl);
myWebView.loadRequest(request);
Now the WebView is invisible, but I'll try firstly to search the solution in a forum.

is this possible to remove advertisement from my webview?

Problem :
actually i am getting url link from api response. and by that link i am loading webview. but when webview load its also showing advertisement so is there any possible way to remove that ad from my webview?
here is my code
override func viewDidLoad() {
super.viewDidLoad()
let url : NSURL = NSURL(string: webviewurl)!
let request : NSURLRequest = NSURLRequest(URL: url)
myweb.loadRequest(request)
}
let me know if is there any possible way to remove ad from webview or may be from url
Usually, you can't change the content of webview you get because what you actually get is a HTML file and then rendered as a webpage.
If the ad only exists in mobile phone, there may be a DNS hijacking,

'NSURLRequest?' does not have a member named 'URL' - Swift

Hi I am really new to coding in Swift, and am trying to follow the codes in this book: http://www.apress.com/9781484202098. Learn iOS 8 App Development 2nd Edition by James Bucanek
In particular, I am working through Chapter 3 - building a URL shortening app, but despite having copied the code exactly, I am getting an error on the code in Page 76:
if let toShorten = webView.request.URL.absoluteString {
which states 'NSURLRequest?' does not have a member named 'URL'.
I have tried googling an answer, but unfortunately have not come across anything. Any response I can find seems to suggest that my code ought to be working (e.g. How to get url which I hit on UIWebView?). This seems to have the closest answer SWIFT: Why I can't get the current URL loaded in UIWebView? but the solution does not appear to work for me. If I add a ? after the request, it will then at least build it, but I then have a nil variable returned.
I am using Xcode v6.1.1. Here is the piece of code that is coming up with the error in ViewController.swift:
let GoDaddyAccountKey = "0123456789abcdef0123456789abcdef" //this is replaced by my actual account key in my own code
var shortenURLConnection: NSURLConnection?
var shortURLData: NSMutableData?
#IBAction func shortenURL( AnyObject ) {
if let toShorten = webView.request?.URL.absoluteString { // ? now added
let encodedURL = toShorten.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let urlString = "http://api.x.co/Squeeze.svc/text/\(GoDaddyAccountKey)?url=\(encodedURL)"
shortURLData = NSMutableData()
if let firstrequest = NSURL(string: urlString) //added if here and removed !
let request = NSURLRequest(URL:firstrequest)
shortenURLConnection = NSURLConnection(request:request, delegate:self)
shortenButton.enabled = false
}
}
}
If you have any suggestions on how I can fix this, I would really appreciate it!
Update:
Following suggestions from Ashley below, I have amended my code so that it is no longer bringing up the error (see comments above). However, it is now no longer running. This appears to be because the urlString is being created as http://api.x.co/Squeeze.svc/text/d558979bb9b84eddb76d8c8dd9740ce3?url=Optional("http://www.apple.com/"). The problem is therefore the Optional() that is included and thus makes it an invalid URL. Does anyone have a suggestion on how to remove this please?
request is an optional property on UIWebView:
var request: NSURLRequest? { get }
also stringByAddingPercentEscapesUsingEncoding returns an optional:
func stringByAddingPercentEscapesUsingEncoding(_ encoding: UInt) -> String?
What you need is to make user of optional binding in a few places:
if let toShorten = webView.request?.URL.absoluteString {
if let encodedURL = toShorten.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
let urlString = "http://api.x.co/Squeeze.svc/text/\(GoDaddyAccountKey)?url=\(encodedURL)"
shortURLData = NSMutableData()
if let firstrequest = NSURL(string: urlString) { // If a method can return a nil, don't force unwrap it
let request = NSURLRequest(URL:first request)
shortenURLConnection = NSURLConnection(request:request, delegate:self)
shortenButton.enabled = false
}
}
}
See Apple's docs on optional chaining for details
See Apple's docs for NSURL class

Resources