Passing dynamic Int variable from one class to another class in Swift
I used NSUserDefaults
to handle this.
So, in the GameScene
just after the class GameScene
is declared (and not in any function) I used
var score = Int()
var defaults = NSUserDefaults.standardUserDefaults()
Then in the didMoveToView(view: SKView)
function in the same class, I used
defaults.setInteger(0, forKey:"score")
So that whenever GameScene
is presented, the current score resets to 0 before you start the game.
Then in your collision function, before the GameOver
scene is about to be presented (but still in the GameScene
class), you use (after your score has been increased or decreased)
defaults.setInteger(score, forKey:"score")
This will set the current score
to the key "score"
in NSUserDefaults
.
Finally, in the GameOver
scene, before you present the score, you can say
let scoreFromGameScene = NSUserDefaults.standardUserDefaults().integerForKey("score")
label.text = "\(scoreFromGameScene)" //Or whatever you use to present the score
This will make sure that you get the current score from the GameScene
so that you can use it in your GameOver
scene. Since the key "score"
will always have SOME integer value, we can retrieve the value without error.
Hope that helps :)
How to pass a variable from a class to another?
You should use delegate protocols. For more information check out this document.
Set up a protocol
in the secondClass
, right after the import
statements, like so:
protocol InformingDelegate {
func valueChanged() -> CGFloat
}
Inside the same secondClass
create a delegate
variable (some suggest that it should be marked as weak
):
var delegate: InformingDelegate?
Then, create some method in which you will access the changed value. You can assign it to value
for example:
func callFromOtherClass() {
value = self.delegate?.valueChanged()
}
This is it for the secondClass
. Now onto the firstClass
.
Here you only need to conform to the protocol by adding InformingDelegate
after the class definition, like this:
class firstClass: UIViewController, InformingDelegate {
...
}
Then, inform the compiler that you are going to be a delegate for the other class by creating its instance, and setting yourself to be the delegate:
var secondVC : secondClass = secondClass()
secondClass.delegate = self
secondClass.callFromOtherClass() // This will call the method in the secondClass
// which will then ask its delegate to trigger a method valueChanged() -
// Who is the delegate? Well, your firstClass, so you better implement
// this method!
The last thing is to actually conform to the protocol by implementing its method:
func valueChanged() -> CGFloat {
return myVariable // which is 5 in your case (value taken from a question)
}
This will assign myVariable
value (5 in this example) to the value
in the other class.
Access variable in different class - Swift
There is an important distinction to be made between "files" in Swift and "classes". Files do not have anything to do with classes. You can define 1000 classes in one file or 1 class in 1000 files (using extensions). Data is held in instances of classes, not in files themselves.
So now to the problem. By calling Main()
you are creating a completely new instance of the Main
class that has nothing to do with the instance that you have hooked up to your Xib file. That is why the value comes out as the default.
What you need to do, is find a way to get a reference to the same instance as the one in your Xib. Without knowing more of the architecture of your app, it is hard for me to make a suggestion as to do that.
One thought, is that you can add a reference to your Main
instance in your Xib using an IBOutlet in your View
. Then you can simply do self.main.getValue()
and it will be called on the correct instance.
Convert dynamic server response in to model class in swift
The decoding of your JSON response always succeeds in the first try (with TempUserResponse
type) because all your properties are optional and decoded using decodeIfPresent<T>(_:forKey:)
function.
So, JSONDecoder
assumes that the value of the key data
in your root object is a TempUserResponse
instance but with all of is properties set to nil
. (none of the property keys are present in the JSON)
In order to avoid that behavior you can set a property that make sense to you, to be mandatory in TempUserResponse
, like for example tempUser
:
struct TempUserResponse : Codable {
let askForMobileNo: Int?
let provider: String?
let providerId: String?
let tempUser: TempUser
enum CodingKeys: String, CodingKey {
case askForMobileNo = "ask_for_mobile_no"
case provider = "provider"
case providerId = "provider_id"
case tempUser = "temp_user"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
askForMobileNo = try values.decodeIfPresent(Int.self, forKey: .askForMobileNo)
provider = try values.decodeIfPresent(String.self, forKey: .provider)
providerId = try values.decodeIfPresent(String.self, forKey: .providerId)
tempUser = try values.decode(TempUser.self, forKey: .tempUser)
}
}
That way the decoding will succeed if the tempUser
key is present in the JSON and will fail when there is not and fall back to the AppUserResponse
decoding.
Update: Another solution would be to merge both structs into one with all of its properties as optionals.
That way your model will be a lot simpler:
struct UserResponse: Codable {
let accessToken: String?
let askForMobileNo: Int?
let tokenType: String?
let user: AppUser?
let provider: String?
let providerId: String?
let tempUser: TempUser?
enum CodingKeys: String, CodingKey {
case accessToken = "access_token"
case askForMobileNo = "ask_for_mobile_no"
case tokenType = "token_type"
case user = "user"
case provider = "provider"
case providerId = "provider_id"
case tempUser = "temp_user"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
accessToken = try values.decodeIfPresent(String.self, forKey: .accessToken)
askForMobileNo = try values.decodeIfPresent(Int.self, forKey: .askForMobileNo)
tokenType = try values.decodeIfPresent(String.self, forKey: .tokenType)
user = try values.decodeIfPresent(AppUser.self, forKey: .user)
provider = try values.decodeIfPresent(String.self, forKey: .provider)
providerId = try values.decodeIfPresent(String.self, forKey: .providerId)
tempUser = try values.decodeIfPresent(TempUser.self, forKey: .tempUser)
}
}
Note: Structs that not changed are not included.
The decoding code will look like this:
let decoder = JSONDecoder()
do {
let responseData = try decoder.decode(ServerResponse<UserResponse>.self, from: Data(jsonString.utf8))
print(responseData)
} catch {
print(error)
}
and you can just check if user
or tempUser
property exist to determine your case.
How to pass int value from one class to another in xcode
First, you should read some docs about objective-c and OOP.
What you are calling classes, are methods. And if you want to pass one variable to a method, you have to declare it in the method declaration:
-(NSArray *)Vehicles:(NSInteger) id2 {
NSString *urlString=[NSString stringWithFormat:@"http://www.tranzlogix.com/tranzlogix_webservice/vehiclelist.php?uid=%d&format=json",id2];
}
And you have to pass it when you call it, if you are calling the method from your class, a correct way will be: [self Vehicles:id2]
But i suggest you to read a lot before asking so basic questions.
How do I update a class variable from inside of a method for visibility of that variable to other classes in Swift?
Change your code in SecondClass like this:
Class SecondClass: UIViewController {
let myfirstClass = FirstClass()
myFirstClass.abc() // changes the tag in your instance of FirstClass
var a = myfirstClass.getTag()
// will print 5 because now you ask the instance,
// where the abc-function was called
}
Call a method with dynamic class name in swift
I liked this question, because it made me to think a lit'bit outside of the box.
I'll answer it, by dividing it into a few parts.
First
call class functions
Class function is basically a Type methods, which can be achieved using the static
word inside the class
context.
Taking that into account, you can get a simple solution, using protocol and passing the class reference (conforming to that protocol) like this:
protocol Aaa{
static func doSomething();
}
class Foo : Aaa{
static func doSomething() {
print("Foo doing something");
}
}
class FooBar : Aaa{
static func doSomething() {
print("FooBar doing something");
}
}
class ActualWork{
//Using class (static) method
func callDynamicClassMethod <T: Aaa> (x: T.Type) {
x.doSomething();
}
}
//This is how you can use it
func usage(){
let aw = ActualWork();
aw.callDynamicClassMethod(x: Foo.self);
aw.callDynamicClassMethod(x: Foo.self);
}
Second
In case you don't really need the method on the class context, you may consider using instance methods. In that case the solution would be even simpler, like this:
protocol Bbb{
func doSomething();
}
class Bar : Bbb{
func doSomething() {
print("Bar instance doing something");
}
}
class BarBar : Bbb{
func doSomething() {
print("BarBar instance doing something");
}
}
class ActualWork{
//Using instance (non-static) method
func callDynamicInstanceMethod <T: Bbb> (x: T){
x.doSomething();
}
}
//This is how you can use it
func usage(){
let aw = ActualWork();
aw.callDynamicInstanceMethod(x: Bar());
aw.callDynamicInstanceMethod(x: BarBar());
}
Third
If you need to use the class func
syntax, as OP originally did:
class func doSomething()
You CANNOT simply use a protocol. Because protocol is not a class...
So compiler won't allow it.
But it's still possible, you can achieve that by using
Selector with NSObject.perform method
like this:
class ActualWork : NSObject{
func callDynamicClassMethod<T: NSObject>(x: T.Type, methodName: String){
x.perform(Selector(methodName));
}
}
class Ccc : NSObject{
@objc class func doSomething(){
print("Ccc class Doing something ");
}
}
class Ddd : NSObject{
@objc class func doSomething(){
print("Ccc class Doing something ");
}
@objc class func doOther(){
print("Ccc class Doing something ");
}
}
//This is how you can use it
func usage() {
let aw = ActualWork();
aw.callDynamicClassMethod(x: Ccc.self, methodName: "doSomething");
aw.callDynamicClassMethod(x: Ddd.self, methodName: "doSomething");
aw.callDynamicClassMethod(x: Ddd.self, methodName: "doOther");
}
Related Topics
Is There a Github Markdown Language Identifier for Swift Code
Xcodebuild -Exportarchive Wont Allow Me to Specify Filename
Compile Time Key Path Checking in Swift
Using Uilexicon to Implement Autocorrect in iOS 8 Keyboard Extension
Swift Change the Tableviewcell Border Color According to Data
How to Change Text Color of Actionsheet in Swiftui
Avoid Automatic Framework Linking in Swift
Xcode 11 - Disable Resize Mode in Catalyst Swift
Toggle Sidebar in Swiftui Navigationview on MACos
Troubles Using Cgpathcontainspoint Swift
How to Unwrap Arbitrarily Deeply Nested Optionals in Swift
Toolbar Is Deleting My Back Button in the Navigationview
Swiftui View Does Not Updated When Observedobject Changed
Swiftui Onmovecommand Actions Aren't Executed
Get the Type of Anyobject Dynamically in Swift
How to Use Multiple Mtlrenderpipelinestates in One Mtlrendercommandencoder