Best place to put server private keys on Xcode project - swift

i'm coding an app with server API calls and I've got a private key for access, my question is: Where should I put that key? Let me explain a little more.
When we work for example in JavaScript we have a .env file, it contains sensitive content and is in most of cases on .gitignore file, so where is a correct place to save and access to those private keys on Xcode? or is correct simply to do something like:
let key = "MY_KEY"
thanks in advance

Even though what Codey said is correct but its much better to use a struct and create variables inside that struct. Simply making a variable 'key' might become troublesome in future as you might end up redeclaring it and losing everything. Also by using a struct, it gives much more clarity for the developer, it would make your code much more understandable.
Instead of going through that trouble do this.
Create a new swift file. Name is something like GlobalVariables.swift (or as Codey said).
Now create a struct inside that file.
struct serverInfo
{
static let key = "KEY"
static let server = "0.0.0.0"
}
You can access these variables anywhere on the program with
let x = serverInfo.key
let y = serverInfo.server

If this is only for development purposes, then you can store your password in the code. But note, that this file shouldn't be uploaded to your repository.
I would suggest to create a separate file (like Config.swift) and write your global configuration constants in this file.
// Config.swift
//
let key = "MY_KEY"
let server = "10.0.0.1"
You can then access these variables everywhere in your project. So this is the file you don't want to commit. Keep in mind, that everyone that uses your project needs such a file in order for the project to compile.

Related

Xcode Playgrounds: Source files are unable to be accessed by each other

I am creating a playground in Xcode and I do not understand why the "Sources" files cannot talk to each other. I am using SpriteKit which means it is ideal to have one swift file per scene, in my case I have one scene per level. I cannot use a quick workaround and add everything into one massive file... there has to be a better way. Both classes for the two swift files are public. You should be able to access them. Thanks!
I get this error when I try to an object from one class, LevelScene, in the other class TitleScene.
After this
let levelScene = LevelScene(fileNamed: "LevelScene")
This happens
Cannot find 'LevelScene' in scope
I am aware of this post. This solution still does not work for me.
Xcode playgrounds can't access swift files in Sources folder
I am on Xcode 12.4.
Thanks!
You need to declare all your classes/struct in each file as public.
So, if you have defined a struct like this in a file:
struct Node {
var id: Int
}
You need to declare is like so:
public struct Node {
var id: Int
}
Then your code should work. You can use a struct from one file in another file as long as you declare them as public. Similar concept goes for any functions/methods inside those structs/classes. Even with this solution, you may find Xcode 12.4 complaining about not finding the type in scope. That, I believe, is a known bug. I have the same bug on my Xcode 12.4. I am able to build and run the code even with that error.

How to make copy of array's elements in the dart

Getting wired issue like main array has been changed if changed value of another array. I think issue is about copying same address, not sure but just thinking of it. I have tried from last 3 hours but unable to get rid from it.
Look at below illustration to get better idea.
List<page> _pageList;
List<page> _orderList = [];
_pageList = _apiResponse.result as List<page>;
_orderList.add(_pageList[0].element);
_orderList[0].title = "XYZ"
//--> Here if I change the `_orderList[0].title` then it also change the `title` inside "_pageList"
How can we prevent the changes in main array?
I got same issue in my one of the project. What I have done is, use json to encode and decode object that help you to make copy of the object so that will not be affected to the main List.
After 3rd line of your code, make changes like below
Elements copyObject = Elements.fromJson(_pageList[0].element.toJson());
// First of all you have to convert your object to the Map and and map to original object like above
_orderList.add(copyObject);
Hope that will help you.
You can use a getter function to create a copy of your list and use that instead of
altering your actual list.
example:
List<Page> get orderList{
return [..._orderList];
}
Lists in Dart store references for complex types, so this is intended behaviour.
From your code:
_orderList.add(_pageList[0].element);
_orderList[0] and _pageList[0].element point to the same reference (if they are non-primitive).
There is no general copy() or clone() method in dart, as far as i know. So you need to copy the object yourself, if you want a separate instance. (see this question)

Hard Coding NSUserActivityTypes for Restoring Different Data Models

As of iOS 13, Apple recommends storing user state using an NSUserActivity object attached to a scene, so I've been trying to a) better understand how NSUserActivity works and b) implement that in my own code. In working through Apple's documentation, I came across this piece of code:
class var activityType: String {
let activityType = ""
// Load our activity type from our Info.plist.
if let activityTypes = Bundle.main.infoDictionary?["NSUserActivityTypes"] {
if let activityArray = activityTypes as? [String] {
return activityArray[0]
}
}
return activityType
}
I understand what this is doing (it looks at the Info.plist file for an entry called "NSUserActivityTypes", if it exists it tries to get the associated array of activityTypes, and then it reads the first item in the array), but what I don't understand is why. In particular, I don't understand why we're only reading the first item in activityArray. In this case we know the first (and only item) is "com.apple.apple-samplecode.StateRestoration.activity" because we have to manually create that plist entry. But I don't understand why we are hard coding looking at the first item of the array in order to get the activity type, because if we know we're just going to get back the String "com.apple.apple-samplecode.StateRestoration.activity", why not just write the code to be this:
class var activityType: String {
return "com.apple.apple-samplecode.StateRestoration.activity"
}
I've never worked with NSUserActivity before, and I understand that it can be (usually is?) used for things other than state preservation/restoration, so there could be many different kinds of useractivities that your app could support (handoff, Siri integration, etc.). So I would assume that we want our code to be as robust as possible in not making any assumptions about the kinds of NSUserActivity objects we might receive.
Maybe someone who has more experience with NSUserActivity can help explain the ways in which NSUserActivity might be handed to my app, and why we can hard code in the first element of an array, while in other places we want to check if a passed-in activity is the right kind of activity (even though we know our array of supported activities has only one kind of activity, so presumably there's only one kind of activity we'd receive in the first place?).
Also, this isn't unique to Apple's sample code... this blog post also takes a similar approach when reading the Info.plist file:
extension Bundle {
var activityType: String {
return Bundle.main.infoDictionary?["NSUserActivityTypes"].flatMap { ($0 as? [String])?.first } ?? ""
}
}
I do have the same doubt when reading the Apple's example of restoring user state using NSUserActivity, because in my past project I always have a Constant.swift to handle all the hardcode string (something like id, or key), for example:
Constants.swift
struct Constants {
static let userActivityTypeA = "com.apple.apple-samplecode.StateRestoration.activityA"
static let userActivityTypeB = "com.apple.apple-samplecode.StateRestoration.activityB"
}
I understand what this is doing (it looks at the Info.plist file for an entry called "NSUserActivityTypes", if it exists it tries to get the associated array of activityTypes, and then it reads the first item in the array), but what I don't understand is why.
In my opinion, it is not a must to follow the Apple's example (adding the activityType in the info.plist & read it using Bundle.main.infoDictionary). Apple just provide a way that is cleaner & can be easily identify what that String is, by providing a fixed key "NSUserActivityTypes" in the info.plist.
(Imagine someday your colleague pick up your project and he may have no idea what is that reverse domain string in the Constants.swift or wherever you placed it.)
why we can hard code in the first element of an array, while in other places we want to check if a passed-in activity is the right kind of activity (even though we know our array of supported activities has only one kind of activity, so presumably there's only one kind of activity we'd receive in the first place?).
It really depends on how many activityType your apps support, for example, you may want to add few more types in the future, like type A go to ViewController A, and type B will open an In-App browsers in your apps. If you know your apps only support one kind of activity, Yes you don't even need to check it, but in general, we always want to confirm what is received and give corresponding respond.
I think that both sample codes are just dummy ways to explain how states work.
There, they use a single restoration ID (com.apple.apple-samplecode.StateRestoration.activity) but your app may have more than that, so as you say, the sample code wouldn't make sense anymore.
Also note that even when using a single restoration ID you have all the NSUserActivity fields (including userInfo) to help you distinguish between states. Of course, it would be dirty to have very different states sharing the same restoration ID.

Lua light userdata

I have a problem with Lua and I don't know if I going in the right direction. In C++ I have a dictionary that I use to pass parameter to a resource manager. This dictionary is really similar to a map of hash and string.
In Lua I want to access to these resource so I need a representation of hashes. Also hashes must be unique cause are used as index in a table. Our hash function is 64bit and I'm working on 32bit enviroment (PS3).
C++ I have somethings like that:
paramMap.insert(std::make_pair(hash64("vehicleId"), std::string("004")));
resourceManager.createResource(ResourceType("Car"), paramMap);
In Lua want use these resources to create a factory for other userdata.
I do stuff like:
function findBike(carId)
bikeParam = { vehicleId = carId }
return ResourceManager.findResource('car', bikeParam)
end
So, sometime parameter are created by Lua, sometime parameter are created by C++.
Cause my hashkey ('vehicleId') is an index of a table it need to be unique.
I have used lightuserdata to implement uint64_t, but cause I'm in a 32bit enviroment I can't simply store int64 in pointer. :(
I have to create a table to store all int64 used by the program and save a reference in userdata.
void pushUInt64(lua_State *L, GEM::GUInt64 v)
{
Int64Ref::Handle handle = Int64Ref::getInstance().allocateSlot(v);
lua_pushlightuserdata(L, reinterpret_cast<void*>(handle));
luaL_setmetatable(L, s_UInt64LuaName);
}
but userdata are never garbage collected. Then my int64 are never released and my table will grow forever.
Also lightuserdata don't keep reference to metadata so they interfere with other light userdata. Checking the implementation the metadata table is added in L->G_->mt_[2].
doing that
a = createLightUserDataType1()
b = createLightUserDataType2()
a:someFunction()
will use the metatable of b.
I thought that metatable where bounded to type.
I'm pretty confused, with the current implementation lightuserdata have a really limited use case.
With Python you have a hash metafunction that is called anytime the type is used as index for a dictionary. It's possible to do something similar?
Sorry for my english, I'm from Italy. :-/

How can I prevent outside code to manipulate contents of the Dictionary?

I want a Dictionary<string, string> property which should not be changed/set by the outside code. To achieve this, I can declare private variable and it's property with get accessor only.
e.g.
private static Dictionary<string, string> myDic = new Dictionary <string, string>();
Public static Dictionary<string, string> MyDictionary
{
get { return myDic;}
}
But in this case, outside code can manipulate 'contents' of the dictionary.
e.g. MYClass.MyDictionary["FirstSampleKey"] = "Replacing original value by New Value";
I dont want any outside code to manipulate contents of the dictionary. How can I achieve this?
I don't believe there is a read only dictionary (which would be nice as there is a ReadOnlyCollection). Your best bet would probably be to not expose the dictionary at all and expose properties/methods that allow the developer to get at the information without allowing them to directly access the dictionary.
If this is something you will be doing a lot of, you can look into either using someone else's ReadOnlyDictionary implementation (there are plenty out there if you Google it), or you can write your own.
I would also say that you could write a method for the developers to look up their words, or else you could return a copy of the dictionary, this way the dictionary works as it do now, but of cause you would have to copy the dictionary every time the get method is called which could take some time if it's a large dictionary.