I want to get device ID in at all classes level in swift which will be included as parameter every time async call made.And I really don't get clearly about Apple Access Control.So,I really need help
So,How to make saving device id at start point and them accessible to all classes for async request?
In app,didFinishLaunchingWithOptions,I will add the following code
let say keychain is the library where i store value
if keychain.get("deviceID") == nil{
keychain.set(UIDevice.currentDevice().identifierForVendor!.UUIDString,forKey : ”deviceID”)
//some private var deviceID = keychain.get(“deviceID”)
}
else{
some private var deviceID = keychain.get(“deviceID”)
}
And I want to access that private var at everywhere in the UIViewController class.
class ViewController : UIViewController {
let deviceID = //some private var with getter?
}
Is there any idea that i can do in swift?using Apple Access Control?
And that problem is connected to that question : Getting Device ID is not unique
define your deviceID as static and you will be able to access it everywhere
after your code to initiate the keychain, set it as a static at some class
class DeviceArg {
static var deviceId = keychain.get(“deviceID”)
}
// some other place in the code
let check = DeviceArg.deviceId //get deviceId
Check My Code :-
var mytoken1: String = deviceToken.description.stringByReplacingOccurrencesOfString("<", withString: "")
var mytoken2: String = mytoken1.stringByReplacingOccurrencesOfString(">", withString: "")
mytoken2 = mytoken2.stringByReplacingOccurrencesOfString(" ", withString: "")
NSUserDefaults.standardUserDefaults().setValue(mytoken2, forKey: "DEVICE_TOKEN")
NSUserDefaults.standardUserDefaults().synchronize()
Related
I have made a file called Constants.swift. Within this, I have made a class like so...
public class WebServices {
static let getMyPlants : String = "plant/getPlants"
static let getMyOrganizations: String = "organization/getOrganizations"
}
Now whenever, I use an api anywhere in my project, I do Webservices.getMyPlants.
Now I also have a base-url for each of the API's. That is mentioned below public class WebServices.... like so..
struct envDev {
var BASEURL : String = "http://api-proj-dev.ii.the-co.com/api/"
}
Now, the base-url for Webservices.getMyOrganizations is different. I want to use a condition within struct envDev that if I have selected Webservices.getMyOrganizations, then I can give a different BASEURL. Something like...
//The below code isn't right. I just wrote it to represent the kind of solution I wish to have.
struct envDev {
var BASEURL : String = "http://api-proj-dev.ii.the-co.com/api/"
if Webservices.getMyOrganizations {
var BASEURL : String = "http://my second base-url.."
}
}
EDIT 1 Giving below the signature of APIHelper
class APIHelper: NSObject {
var API: NSString
var json: NSString
var receivedJSON: NSString?
var arrResult: NSMutableArray = []
let esmatBaseUrl = AppDelegate().currentUser //This is given in AppDelegate as `var currentUser = envDev()`
()
EDIT 2 Inclusion of baseUrl computed property in APIHelper & the error.
class APIHelper: NSObject {
var API: NSString
var json: NSString
var receivedJSON: NSString?
var arrResult: NSMutableArray = []
let esmatBaseUrl = AppDelegate().currentUser //This is given in AppDelegate as `var currentUser = envDev()`
()
var baseUrl: String {
esmatBaseUrl.baseUrl(forApi: API as String) // Here I'm getting the error as `Value of type 'envDev' has no member 'baseUrl'`
}
envDev has no way of knowing what happens in APIHelper, so you need a way to pass in the API from APIHelper to envDev. This means that BASEURL should not be a property, but a method:
func baseUrl(forApi api: String) -> String {
switch api {
case WebServices.getMyPlants: return "some url"
case WebServices.getMyOrganizations: return "some other url"
default: fatalError()
}
}
Then in APIHelper, you can add a baseUrl computed property that calls the above method:
var baseUrl: String {
esmatBaseUrl.baseUrl(forApi: API as String)
}
This would mean that you need to change all occurrences of esmatBaseUrl.BASEURL in your existing code to just baseUrl.
Also, I would suggest not using NSString, NSArray, etc in Swift. You should their Swift counterparts: String and [T].
I understood your query. You want to create an ENUM for your server-environment's, instead of hard-coding baseUrl's you probably want to use ENUMS to select different environments, right.
So accordingly, I've created an ENUM for you to add different server-environments so it will be feasible for you to use it frequently every-where.
private enum ServerEnv: String {
case stage, prod, test, my_plants, my_organization
var domainValue: String {
switch self {
case .test, .my_plants: return "http://api-testing-proj-dev.ii.the-co.com/api/"
case .stage: return "http://api-staging-proj-dev.ii.the-co.com/api/"
case .prod: return "http://api-production-proj-dev.ii.the-co.com/api/"
case .my_organization: return "http://api-my_organization-proj-dev.ii.the-co.com/api/"
}
}
}
Example :
let baseUrl = ServerEnv.my_organization.domainValue
Output => baseURL = "http://api-my_organization-proj-dev.ii.the-co.com/api/"
let baseUrl = ServerEnv.my_plants.domainValue
Output => baseURL = "http://api-testing-proj-dev.ii.the-co.com/api/"
I hope, I've solved your query here.
Happy Coding :-)
I'm trying to implement a ORM layer on top of Couchbase Lite iOS 2.0, now it did removed the CBLModel apis which make it a little bit difficult to use.
I'm using a Reflection lib and its Mappable protocol(which is renamed to ORMMappable in the following code) to simplify the mapping apis.
Here's the error message:
let t = Self.cast_id_type(type: link, obj: value)
Cannot invoke 'cast_id_type' with an argument list of type '(type: ORMMappable.Type, obj: Any?)'
Expected an argument list of type '(type: D.Type, obj: Any?)'
And here's the problematic code
typealias MappableDictionary = [String : Any]
class IDString<T:ORMMappable> : NSString{
func load_object(){
}
}
struct MapMeta{
var ignores : [String] = []
var mapping : [String:ORMMappable.Type] = [:]
}
protocol ORMMappable {
var id : NSString {get set}
static var _meta : MapMeta{get}
init(dictionary: MappableDictionary) throws
}
extension ORMMappable {
init() throws{
try self.init(dictionary: [:] as MappableDictionary)
}
static func cast_id_type<D:ORMMappable>(type: D.Type,obj: Any?) -> IDString<D>?{
if let o = obj as? IDString<D>{
return o
}
return nil
}
init(dictionary: MappableDictionary) throws {
self = try construct { property in
let meta = Self._meta
if let value = dictionary[property.key] {
if let type = property.type as? ORMMappable.Type, let value = value as? MappableDictionary {
return try type.init(dictionary: value)
}
else if let link = meta.mapping[property.key]
{
let t = Self.cast_id_type(type: link, obj: value)
print(link)
//return t
return nil
}
else {
return value
}
} else {
return nil
//throw Error.missingRequiredValue(key: property.key)
}
}
}
}
A example of usage is
struct TestObject : ORMMappable{
static var _meta: MapMeta{
return MapMeta(ignores: [], mapping: ["link_id":TestObject2.self])
}
var id : NSString
var name : String?
var age : Int?
var link_id : IDString<TestObject2>?
}
IDString is holder for a link to other ORMMappable compatible class, mapping maps from String(property name) to a ORMMappable compatible class, and cast_id_type does check the mapping and trying to cast from the pointer of value to the StringID object. The error itself makes me quite confused here,
static func cast_id_type<D:ORMMappable>(type: D.Type,obj: Any?) -> IDString<D>?
D should be a ORMMappable compatible class, where I give is a value of a [String:ORMMappable.Type], but it rises ORMMappable.Type is not D.Type, how does this comes from?
Also I'm looking forward if there any better ways to do ORM in swift, currently the code does working with dynamic object creation, but when comes with ORM relation, it really drove me nuts here, just looking for ways to manage it in a easier and more manageable ways, where currently it looks like there are not much functionalities to do meta programming, a lot of other ORM libs still using objc, which is much more easier(but boilerplate) on dynamic instance creation or class inspection.
Thanks very much for the help, any hints will be real appreciated :)
Removed all generics solved the problem, it won't inferred in runtime environment.
I have a Localization struct which helps to manage local keys.
struct Localization {
//Home
static let HomeHeader = "Home_Header"
static let HomeStatusActive = "Home_Status_Active"
static let HomeStatusDelayed = "Home_Status_Delayed"
}
Also, I have string extension which named as local to gives me the key from Localizable.strings file.
extension String {
var local : String {
return LocalizationManager.getLocalizedString(key: self)
}
}
So when I need to localization key I use it like this;
titleLabel.text = Localization.HomeHeader.local
My question; Is there a way to perform an extension to use on every constant of struct without calling .local every time?
Basically, I want to call as below;
titleLabel.text = Localization.HomeHeader
Thanks a lot.
To do minimal changes on what you have implemented till now. You could simply add local after string values.
struct Localization {
//Home
static let HomeHeader = "Home_Header".local
static let HomeStatusActive = "Home_Status_Active".local
static let HomeStatusDelayed = "Home_Status_Delayed".local
}
extension String {
var local : String {
return LocalizationManager.getLocalizedString(key: self)
}
}
Then you will be able to use it like:
titleLabel.text = Localization.HomeHeader
Please check below may be helpful to you
You can keep all your localised string in one place
struct ConstantsLocalized {
static var key_loading: String {
return "key_loading".localized()
}
static var key_placeholder_email: String {
return "key_placeholder_email".localized()
}
}
And you can access it with ConstantsLocalized.key_loading
EDIT
I need to add one more advantage with this method, If you have in app localisation means user can change language from app it self then it is the best solution because you can get localise string every time
Hope it is helpful
I'm new in Realm and I tried to add an Array as I did with strings and I ended up with some errors. So after a little search I found out a solution:
class Sensors : Object {
dynamic var name = ""
dynamic var message = ""
var topic: [String] {
get {
return _backingNickNames.map { $0.stringValue }
}
set {
_backingNickNames.removeAll()
_backingNickNames.append(objectsIn: newValue.map({ RealmString(value: [$0]) }))
}
}
let _backingNickNames = List<RealmString>()
override static func ignoredProperties() -> [String] {
return ["topic"]
}
}
class RealmString: Object {
dynamic var stringValue = ""
}
This is working very good, now I want to add another array inside this class.
If someone knows any other ways to add arrays with realm please share it.
Thanks in advance
As a general rule it's way more efficient to use the one-to-many relationships provided by Realm instead of trying to emulate them by using arrays (Realm's collections are lazy, the objects contained are instantiated only when needed as opposed to plain Swift arrays).
In your case, if I understand correctly what you're trying to do, you want to add [RealmString] Swift arrays to the _backingNickNames list.
Why not use the append(objectsIn:) method of Realm's List class (see here), like this:
// Dog model
class Dog: Object {
dynamic var name = ""
dynamic var owner: Person?
}
// Person model
class Person: Object {
dynamic var name = ""
dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
let dogs = List<Dog>()
}
let jim = Person()
let dog1 = Dog()
let dog2 = Dog()
// here is where the magic happens
jim.dogs.append(objectsIn: [dog1, dog2])
If you want to do the opposite (convert from a List to an Array) just do :
let dogsArray = Array(jim.dogs)
• • • • • • • •
Back to your own posted solution, you could easily refactor the model to accommodate this. Each Sensor object could have several Topic and several Message objects attached.
Just ditch the message and topic computed properties and rename topicV and messageV to topics and messages respectively. Also rename RealmString to Topic and RealmString1 to Message.
Now, you could easily iterate through the, say, topics attached to a sensor like this :
for topic in sensor1.topics { ... }
Or if you want to attach a message to a sensor you could do something like this (don't forget to properly add the newly created object to the DB first):
let message1 = Message()
message1.stringValue = "Some text"
sensor2.messages.append(message1)
So, no need to use intermediary Swift Arrays.
After testing I managed to add another array like that:
class Sensors : Object {
dynamic var type = ""
dynamic var name = ""
dynamic var badge = 0
var topic: [String] {
get {
return topicV.map { $0.stringValue }
}
set {
topicV.removeAll()
topicV.append(objectsIn: newValue.map({ RealmString(value: [$0]) }))
}
}
var message: [String] {
get {
return messageV.map { $0.stringValue1 }
}
set {
messageV.removeAll()
messageV.append(objectsIn: newValue.map({ RealmString1(value: [$0]) }))
}
}
let topicV = List<RealmString>()
let messageV = List<RealmString1>()
override static func ignoredProperties() -> [String] {
return ["topic", "message"]
}
}
class RealmString: Object {
dynamic var stringValue = ""
}
class RealmString1: Object {
dynamic var stringValue1 = ""
}
What bogdanf has said, and the way you've implemented it are both correct.
Basic value types aside, Realm can only store references to singular Realm Object objects, as well as arrays of Objects using the List type. As such, if you want to save an array of types, it's necessary to encapsulate any basic types you want to save (like a String here) in a convenience Realm Object.
Like bogdanf said, it's not recommended to convert Realm Lists to standard Swift arrays and back again, since you lose the advantages of Realm's lazy-loading features (which can cause both performance and memory issues), but memory issues can at least be mitigated by enclosing the code copying data out of Realm in an #autoreleasepool block.
class MyObject: Object {
dynamic var childObject: MyObject?
let objectList = List<MyObject>()
}
So in review, it's best practice to work directly with Realm List objects whenever possible, and to use #autoreleasepool any time you do actually want to loop through every child object in a Realm. :)
I am using Swift.
This question talks about the Parse service.
I've read ways using both the #NSManaged and dynamic key-words, so I decided for my example to implement them both. The issue here is that in the User object of my data manager, I'm noticing that additional information is not being stored in the database. For my application I would like to store some additional information in the User table, such as their first and last name. Here's an example:
import Parse
public class User : PFUser {
#NSManaged public var firstName: String!
dynamic public var lastName: String!
override public class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
init(email: String, password: String) {
super.init();
self.username = email;
self.email = email;
self.password = password;
self.firstName = "MyFirstName";
self.lastName = "MyLastName";
}
}
Here's the code I'm using to initialize and send off the data:
#IBAction func register() {
let newUser = User(email: "myemail#provider.com", password: "my password");
newUser.signUpInBackgroundWithBlock { (success, error) -> Void in
if error == nil {
print("Success")
} else {
print(error);
}
}
}
Edit: Upon playing around in the dashboard it seems like fields that are added to the User table / document / whatever you want to call it in a schema less database are automatically removed. This would indicate that I would need to create another class (IE: UserInfo) to store all of the users information, such as first and last name. Is this correct? If so that seems a little odd, as it would increase the amount of requests to login to the application. (One for validation, one for retrieving information). Is this the correct way of handling this?
Adding properties to a subclass won't them automatically added to the PFUser instance. You will have to use the PFObject methods to set the properties and then save the PFUser object.
The Parse Documentation gives an example of setting an extra phone property on the PFUser instance before calling signup. This is how you can add the firstName and lastName properties to PFUser.